on da36a01 help sign in
139 lines 4.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 hoist
13 , generally
15 -- * Transform Inner Monad
16 , liftInner
17 , usingReaderT
18 , runReaderT
19 , evalStateT
20 , usingStateT
21 , runStateT
22 )
23where
25#include "inline.hs"
27import Control.Monad.Trans.Reader (ReaderT)
28import Control.Monad.Trans.State.Strict (StateT)
29import Control.Monad.Trans.Class (MonadTrans(..))
30import Data.Functor.Identity (Identity (..))
31import Streamly.Internal.Data.Stream.Type
32 (Stream, fromStreamK, toStreamK, fromStreamD, toStreamD)
34import qualified Streamly.Internal.Data.Stream.StreamD as D
35import qualified Streamly.Internal.Data.Stream.StreamK as K
37-- $setup
38-- >>> :m
39-- >>> import Streamly.Internal.Data.Stream as Stream
41------------------------------------------------------------------------------
42-- Generalize the underlying monad
43------------------------------------------------------------------------------
45-- | Transform the inner monad of a stream using a natural transformation.
46--
47-- / Internal/
48--
49{-# INLINE hoist #-}
50hoist :: (Monad m, Monad n)
51 => (forall x. m x -> n x) -> Stream m a -> Stream n a
52hoist f xs = fromStreamK $ K.hoist f (toStreamK xs)
54-- | Generalize the inner monad of the stream from 'Identity' to any monad.
55--
56-- / Internal/
57--
58{-# INLINE generally #-}
59generally :: Monad m => Stream Identity a -> Stream m a
60generally xs = fromStreamK $ K.hoist (return . runIdentity) (toStreamK xs)
62------------------------------------------------------------------------------
63-- Add and remove a monad transformer
64------------------------------------------------------------------------------
66-- | Lift the inner monad @m@ of a stream @Stream m a@ to @tr m@ using the monad
67-- transformer @tr@.
68--
69-- @since 0.9.0
70{-# INLINE liftInner #-}
71liftInner :: (Monad m, MonadTrans tr, Monad (tr m))
72 => Stream m a -> Stream (tr m) a
73liftInner xs = fromStreamD $ D.liftInner (toStreamD xs)
75------------------------------------------------------------------------------
76-- Sharing read only state in a stream
77------------------------------------------------------------------------------
79-- | Evaluate the inner monad of a stream as 'ReaderT'.
80--
81-- @since 0.9.0
82{-# INLINE runReaderT #-}
83runReaderT :: Monad m => m s -> Stream (ReaderT s m) a -> Stream m a
84runReaderT s xs = fromStreamD $ D.runReaderT s (toStreamD xs)
86-- | Run a stream transformation using a given environment.
87--
88-- See also: 'Serial.map'
89--
90-- / Internal/
91--
92{-# INLINE usingReaderT #-}
93usingReaderT
94 :: Monad m
95 => m r
96 -> (Stream (ReaderT r m) a -> Stream (ReaderT r m) a)
97 -> Stream m a
98 -> Stream m a
99usingReaderT r f xs = runReaderT r $ f $ liftInner xs
101------------------------------------------------------------------------------
102-- Sharing read write state in a stream
103------------------------------------------------------------------------------
105-- | Evaluate the inner monad of a stream as 'StateT'.
106--
107-- >>> evalStateT s = fmap snd . Stream.runStateT s
108--
109-- / Internal/
110--
111{-# INLINE evalStateT #-}
112evalStateT :: Monad m => m s -> Stream (StateT s m) a -> Stream m a
113-- evalStateT s = fmap snd . runStateT s
114evalStateT s xs = fromStreamD $ D.evalStateT s (toStreamD xs)
116-- | Run a stateful (StateT) stream transformation using a given state.
117--
118-- >>> usingStateT s f = Stream.evalStateT s . f . Stream.liftInner
119--
120-- See also: 'scan'
121--
122-- / Internal/
123--
124{-# INLINE usingStateT #-}
125usingStateT
126 :: Monad m
127 => m s
128 -> (Stream (StateT s m) a -> Stream (StateT s m) a)
129 -> Stream m a
130 -> Stream m a
131usingStateT s f = evalStateT s . f . liftInner
133-- | Evaluate the inner monad of a stream as 'StateT' and emit the resulting
134-- state and value pair after each step.
135--
136-- @since 0.9.0
137{-# INLINE runStateT #-}
138runStateT :: Monad m => m s -> Stream (StateT s m) a -> Stream m (s, a)
139runStateT s xs = fromStreamD $ D.runStateT s (toStreamD xs)