on efe0be3 help sign in
95 lines 3.2 kB history raw
1-- |
2-- Module : Streamly.Internal.Data.Stream.Lift
3-- Copyright : (c) 2019 Composewell Technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
6-- Stability : experimental
7-- Portability : GHC
9module Streamly.Internal.Data.Stream.Lift
10 (
11 -- * Generalize Inner Monad
12 morphInner
13 , generalizeInner
15 -- * Transform Inner Monad
16 , liftInnerWith
17 , runInnerWith
18 , runInnerWithState
19 )
20where
22import Data.Functor.Identity (Identity (..))
23import Streamly.Internal.Data.Stream.Type
24 (Stream, fromStreamD, toStreamD, fromStreamK, toStreamK)
26import qualified Streamly.Internal.Data.Stream as D
27import qualified Streamly.Internal.Data.StreamK as K
29-- $setup
30-- >>> :m
31-- >>> import Data.Functor.Identity (runIdentity)
32-- >>> import Streamly.Internal.Data.Stream as Stream
34------------------------------------------------------------------------------
35-- Generalize the underlying monad
36------------------------------------------------------------------------------
38-- | Transform the inner monad of a stream using a natural transformation.
39--
40-- Example, generalize the inner monad from Identity to any other:
41--
42-- >>> generalizeInner = Stream.morphInner (return . runIdentity)
43--
44-- Also known as hoist.
45--
46-- /CPS/
47{-# INLINE morphInner #-}
48morphInner :: (Monad m, Monad n)
49 => (forall x. m x -> n x) -> Stream m a -> Stream n a
50morphInner f xs = fromStreamK $ K.hoist f (toStreamK xs)
52-- | Generalize the inner monad of the stream from 'Identity' to any monad.
53--
54-- Definition:
55--
56-- >>> generalizeInner = Stream.morphInner (return . runIdentity)
57--
58-- /CPS/
59--
60{-# INLINE generalizeInner #-}
61generalizeInner :: Monad m => Stream Identity a -> Stream m a
62generalizeInner = morphInner (return . runIdentity)
63 -- fromStreamK $ K.hoist (return . runIdentity) (toStreamK xs)
65------------------------------------------------------------------------------
66-- Add and remove a monad transformer
67------------------------------------------------------------------------------
69-- | Lift the inner monad @m@ of a stream @Stream m a@ to @t m@ using the
70-- supplied lift function.
71--
72{-# INLINE liftInnerWith #-}
73liftInnerWith :: (Monad m, Monad (t m))
74 => (forall b. m b -> t m b) -> Stream m a -> Stream (t m) a
75liftInnerWith lift xs = fromStreamD $ D.liftInnerWith lift (toStreamD xs)
77-- | Evaluate the inner monad of a stream using the supplied runner function.
78--
79{-# INLINE runInnerWith #-}
80runInnerWith :: (Monad m, Applicative (t m)) =>
81 (forall b. t m b -> m b) -> Stream (t m) a -> Stream m a
82runInnerWith run xs = fromStreamD $ D.runInnerWith run (toStreamD xs)
84-- | Evaluate the inner monad of a stream using the supplied stateful runner
85-- function and the initial state. The state returned by an invocation of the
86-- runner is supplied as input state to the next invocation.
87--
88{-# INLINE runInnerWithState #-}
89runInnerWithState :: (Monad m, Applicative (t m)) =>
90 (forall b. s -> t m b -> m (b, s))
91 -> m s
92 -> Stream (t m) a
93 -> Stream m (s, a)
94runInnerWithState run initial xs =
95 fromStreamD $ D.runInnerWithState run initial (toStreamD xs)