on efe0be3 help sign in
135 lines 4.2 kB history raw
1-- |
2-- Module : Streamly.Internal.Data.Stream.Transformer
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.Transformer
10 (
11 foldlT
12 , foldrT
14 , liftInner
15 , usingReaderT
16 , runReaderT
17 , evalStateT
18 , usingStateT
19 , runStateT
20 )
21where
23import Control.Monad.Trans.Class (MonadTrans)
24import Control.Monad.Trans.Reader (ReaderT)
25import Control.Monad.Trans.State.Strict (StateT)
26import Streamly.Internal.Data.Stream.Type (Stream, fromStreamD, toStreamD)
28import qualified Streamly.Internal.Data.Stream.StreamD.Transformer as D
30-- $setup
31-- >>> :m
32-- >>> import Control.Monad.Trans.Class (lift)
33-- >>> import Control.Monad.Trans.Identity (runIdentityT)
34-- >>> import qualified Streamly.Internal.Data.Stream as Stream
36-- | Lazy left fold to a transformer monad.
37--
38{-# INLINE foldlT #-}
39foldlT :: (Monad m, Monad (s m), MonadTrans s)
40 => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
41foldlT f z s = D.foldlT f z (toStreamD s)
43-- | Right fold to a transformer monad. This is the most general right fold
44-- function. 'foldrS' is a special case of 'foldrT', however 'foldrS'
45-- implementation can be more efficient:
46--
47-- >>> foldrS = Stream.foldrT
48--
49-- >>> step f x xs = lift $ f x (runIdentityT xs)
50-- >>> foldrM f z s = runIdentityT $ Stream.foldrT (step f) (lift z) s
51--
52-- 'foldrT' can be used to translate streamly streams to other transformer
53-- monads e.g. to a different streaming type.
54--
55-- /Pre-release/
56{-# INLINE foldrT #-}
57foldrT :: (Monad m, Monad (s m), MonadTrans s)
58 => (a -> s m b -> s m b) -> s m b -> Stream m a -> s m b
59foldrT f z s = D.foldrT f z (toStreamD s)
61------------------------------------------------------------------------------
62-- Add and remove a monad transformer
63------------------------------------------------------------------------------
65-- | Lift the inner monad @m@ of @Stream m a@ to @t m@ where @t@ is a monad
66-- transformer.
67--
68{-# INLINE liftInner #-}
69liftInner :: (Monad m, MonadTrans t, Monad (t m))
70 => Stream m a -> Stream (t m) a
71liftInner xs = fromStreamD $ D.liftInner (toStreamD xs)
73------------------------------------------------------------------------------
74-- Sharing read only state in a stream
75------------------------------------------------------------------------------
77-- | Evaluate the inner monad of a stream as 'ReaderT'.
78--
79{-# INLINE runReaderT #-}
80runReaderT :: Monad m => m s -> Stream (ReaderT s m) a -> Stream m a
81runReaderT s xs = fromStreamD $ D.runReaderT s (toStreamD xs)
83-- | Run a stream transformation using a given environment.
84--
85-- See also: 'Serial.map'
86--
87-- / Internal/
88--
89{-# INLINE usingReaderT #-}
90usingReaderT
91 :: Monad m
92 => m r
93 -> (Stream (ReaderT r m) a -> Stream (ReaderT r m) a)
94 -> Stream m a
95 -> Stream m a
96usingReaderT r f xs = runReaderT r $ f $ liftInner xs
98------------------------------------------------------------------------------
99-- Sharing read write state in a stream
100------------------------------------------------------------------------------
102-- | Evaluate the inner monad of a stream as 'StateT'.
103--
104-- >>> evalStateT s = fmap snd . Stream.runStateT s
105--
106-- / Internal/
107--
108{-# INLINE evalStateT #-}
109evalStateT :: Monad m => m s -> Stream (StateT s m) a -> Stream m a
110-- evalStateT s = fmap snd . runStateT s
111evalStateT s xs = fromStreamD $ D.evalStateT s (toStreamD xs)
113-- | Run a stateful (StateT) stream transformation using a given state.
114--
115-- >>> usingStateT s f = Stream.evalStateT s . f . Stream.liftInner
116--
117-- See also: 'scan'
118--
119-- / Internal/
120--
121{-# INLINE usingStateT #-}
122usingStateT
123 :: Monad m
124 => m s
125 -> (Stream (StateT s m) a -> Stream (StateT s m) a)
126 -> Stream m a
127 -> Stream m a
128usingStateT s f = evalStateT s . f . liftInner
130-- | Evaluate the inner monad of a stream as 'StateT' and emit the resulting
131-- state and value pair after each step.
132--
133{-# INLINE runStateT #-}
134runStateT :: Monad m => m s -> Stream (StateT s m) a -> Stream m (s, a)
135runStateT s xs = fromStreamD $ D.runStateT s (toStreamD xs)