on master help sign in
Move foldrT/foldlT to transformer module
commit3c10a1febf4dbbfbac479c34520b0b92eb9d0604 authorHarendra Kumar <harendra@composewell.com> dateFri 18 Nov 2022, 12:44 (4 years ago) parenta358a74
7 files changed+88−87
core/src/Streamly/Internal/Data/Stream/StreamD/Transform.hs+1−17 core/src/Streamly/Internal/Data/Stream/StreamD/Transformer.hs+34−2 core/src/Streamly/Internal/Data/Stream/StreamD/Type.hs−17 core/src/Streamly/Internal/Data/Stream/StreamK.hs−27 core/src/Streamly/Internal/Data/Stream/StreamK/Transformer.hs+28−1 core/src/Streamly/Internal/Data/Stream/Transform.hs−20 core/src/Streamly/Internal/Data/Stream/Transformer.hs+25−3
core/src/Streamly/Internal/Data/Stream/StreamD/Transform.hs+1−17
@@ -30,9 +30,7 @@ module Streamly.Internal.Data.Stream.StreamD.Transform
3030
3131 -- * Folding
3232 , foldrS
33− , foldrT
3433 , foldlS
35− , foldlT
3634
3735 -- * Scanning By 'Fold'
3836 , postscanOnce -- XXX rename to postscan
@@ -123,14 +121,12 @@ where
123121#include "inline.hs"
124122
125123import Control.Monad (void)
126−import Control.Monad.Trans.Class (MonadTrans(lift))
127124import Data.Maybe (fromJust, isJust)
128125import Fusion.Plugin.Types (Fuse(..))
129−import GHC.Types (SPEC(..))
130126
131127import Streamly.Internal.Data.Fold.Type (Fold(..))
132128import Streamly.Internal.Data.Pipe.Type (Pipe(..), PipeState(..))
133−import Streamly.Internal.Data.SVar.Type (defState, adaptState)
129+import Streamly.Internal.Data.SVar.Type (adaptState)
134130
135131import qualified Streamly.Internal.Data.Fold.Type as FL
136132import qualified Streamly.Internal.Data.Pipe.Type as Pipe
@@ -175,18 +171,6 @@ transform (Pipe pstep1 pstep2 pstate) (Stream step state) =
175171-- Transformation Folds
176172------------------------------------------------------------------------------
177173
178−{-# INLINE_NORMAL foldlT #-}
179−foldlT :: (Monad m, Monad (s m), MonadTrans s)
180− => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
181−foldlT fstep begin (Stream step state) = go SPEC begin state
182− where
183− go !_ acc st = do
184− r <- lift $ step defState st
185− case r of
186− Yield x s -> go SPEC (fstep acc x) s
187− Skip s -> go SPEC acc s
188− Stop -> acc
189−
190174-- Note, this is going to have horrible performance, because of the nature of
191175-- the stream type (i.e. direct stream vs CPS). Its only for reference, it is
192176-- likely be practically unusable.
core/src/Streamly/Internal/Data/Stream/StreamD/Transformer.hs+34−2
@@ -10,8 +10,11 @@
1010
1111module Streamly.Internal.Data.Stream.StreamD.Transformer
1212 (
13+ foldlT
14+ , foldrT
15+
1316 -- * Transform Inner Monad
14− liftInner
17+ , liftInner
1518 , runReaderT
1619 , evalStateT
1720 , runStateT
@@ -23,13 +26,42 @@ where
2326import Control.Monad.Trans.Class (MonadTrans(lift))
2427import Control.Monad.Trans.Reader (ReaderT)
2528import Control.Monad.Trans.State.Strict (StateT)
26−import Streamly.Internal.Data.SVar.Type (adaptState)
29+import GHC.Types (SPEC(..))
30+import Streamly.Internal.Data.SVar.Type (defState, adaptState)
2731
2832import qualified Control.Monad.Trans.Reader as Reader
2933import qualified Control.Monad.Trans.State.Strict as State
3034
3135import Streamly.Internal.Data.Stream.StreamD.Type
3236
37+{-# INLINE_NORMAL foldlT #-}
38+foldlT :: (Monad m, Monad (s m), MonadTrans s)
39+ => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
40+foldlT fstep begin (Stream step state) = go SPEC begin state
41+ where
42+ go !_ acc st = do
43+ r <- lift $ step defState st
44+ case r of
45+ Yield x s -> go SPEC (fstep acc x) s
46+ Skip s -> go SPEC acc s
47+ Stop -> acc
48+
49+-- Right fold to some transformer (T) monad. This can be useful to implement
50+-- stateless combinators like map, filtering, insertions, takeWhile, dropWhile.
51+--
52+{-# INLINE_NORMAL foldrT #-}
53+foldrT :: (Monad m, Monad (t m), MonadTrans t)
54+ => (a -> t m b -> t m b) -> t m b -> Stream m a -> t m b
55+foldrT f final (Stream step state) = go SPEC state
56+ where
57+ {-# INLINE_LATE go #-}
58+ go !_ st = do
59+ r <- lift $ step defState st
60+ case r of
61+ Yield x s -> f x (go SPEC s)
62+ Skip s -> go SPEC s
63+ Stop -> final
64+
3365-------------------------------------------------------------------------------
3466-- Transform Inner Monad
3567-------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Stream/StreamD/Type.hs−17
@@ -47,7 +47,6 @@ module Streamly.Internal.Data.Stream.StreamD.Type
4747 , foldEither
4848
4949 -- * Right Folds
50− , foldrT
5150 , foldrM
5251 , foldrMx
5352 , foldr
@@ -430,22 +429,6 @@ foldrS f final (Stream step state) = go SPEC state
430429 Skip s -> go SPEC s
431430 Stop -> final
432431
433−-- Right fold to some transformer (T) monad. This can be useful to implement
434−-- stateless combinators like map, filtering, insertions, takeWhile, dropWhile.
435−--
436−{-# INLINE_NORMAL foldrT #-}
437−foldrT :: (Monad m, Monad (t m), MonadTrans t)
438− => (a -> t m b -> t m b) -> t m b -> Stream m a -> t m b
439−foldrT f final (Stream step state) = go SPEC state
440− where
441− {-# INLINE_LATE go #-}
442− go !_ st = do
443− r <- lift $ step defState st
444− case r of
445− Yield x s -> f x (go SPEC s)
446− Skip s -> go SPEC s
447− Stop -> final
448−
449432------------------------------------------------------------------------------
450433-- Left Folds
451434------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Stream/StreamK.hs−27
@@ -73,12 +73,10 @@ module Streamly.Internal.Data.Stream.StreamK
7373 , foldr
7474 , foldr1
7575 , foldrM
76− , foldrT
7776
7877 , foldl'
7978 , foldlM'
8079 , foldlS
81− , foldlT
8280 , foldlx'
8381 , foldlMx'
8482 , fold
@@ -178,7 +176,6 @@ where
178176#include "assert.hs"
179177
180178import Control.Monad.Catch (MonadThrow, throwM)
181−import Control.Monad.Trans.Class (MonadTrans(lift))
182179import Control.Monad (void, join)
183180import Streamly.Internal.Data.Fold.Type (Fold(..))
184181import Streamly.Internal.Data.SVar.Type (adaptState, defState)
@@ -274,18 +271,6 @@ fromList = fromFoldable
274271foldr :: Monad m => (a -> b -> b) -> b -> Stream m a -> m b
275272foldr step acc = foldrM (\x xs -> xs >>= \b -> return (step x b)) (return acc)
276273
277−-- | Right associative fold to an arbitrary transformer monad.
278−{-# INLINE foldrT #-}
279−foldrT :: (Monad m, Monad (s m), MonadTrans s)
280− => (a -> s m b -> s m b) -> s m b -> Stream m a -> s m b
281−foldrT step final = go
282− where
283− go m1 = do
284− res <- lift $ uncons m1
285− case res of
286− Just (h, t) -> step h (go t)
287− Nothing -> final
288−
289274{-# INLINE foldr1 #-}
290275foldr1 :: Monad m => (a -> a -> a) -> Stream m a -> m (Maybe a)
291276foldr1 step m = do
@@ -379,18 +364,6 @@ foldBreak fld strm = do
379364foldlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> m b
380365foldlM' step begin = foldlMx' step begin return
381366
382−-- | Lazy left fold to an arbitrary transformer monad.
383−{-# INLINE foldlT #-}
384−foldlT :: (Monad m, Monad (s m), MonadTrans s)
385− => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
386−foldlT step = go
387− where
388− go acc m1 = do
389− res <- lift $ uncons m1
390− case res of
391− Just (h, t) -> go (step acc h) t
392− Nothing -> acc
393−
394367------------------------------------------------------------------------------
395368-- Specialized folds
396369------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Stream/StreamK/Transformer.hs+28−1
@@ -8,7 +8,10 @@
88--
99module Streamly.Internal.Data.Stream.StreamK.Transformer
1010 (
11− liftInner
11+ foldlT
12+ , foldrT
13+
14+ , liftInner
1215 , evalStateT
1316 )
1417where
@@ -20,6 +23,30 @@ import Streamly.Internal.Data.Stream.StreamK
2023
2124import qualified Control.Monad.Trans.State.Strict as State
2225
26+-- | Lazy left fold to an arbitrary transformer monad.
27+{-# INLINE foldlT #-}
28+foldlT :: (Monad m, Monad (s m), MonadTrans s)
29+ => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
30+foldlT step = go
31+ where
32+ go acc m1 = do
33+ res <- lift $ uncons m1
34+ case res of
35+ Just (h, t) -> go (step acc h) t
36+ Nothing -> acc
37+
38+-- | Right associative fold to an arbitrary transformer monad.
39+{-# INLINE foldrT #-}
40+foldrT :: (Monad m, Monad (s m), MonadTrans s)
41+ => (a -> s m b -> s m b) -> s m b -> Stream m a -> s m b
42+foldrT step final = go
43+ where
44+ go m1 = do
45+ res <- lift $ uncons m1
46+ case res of
47+ Just (h, t) -> step h (go t)
48+ Nothing -> final
49+
2350------------------------------------------------------------------------------
2451-- Lifting inner monad
2552------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Stream/Transform.hs−20
@@ -14,7 +14,6 @@ module Streamly.Internal.Data.Stream.Transform
1414
1515 -- * Folding
1616 , foldrS
17− , foldrT
1817
1918 -- * Mapping
2019 -- | Stateless one-to-one maps.
@@ -144,7 +143,6 @@ where
144143import Control.Concurrent (threadDelay)
145144import Control.Monad (void)
146145import Control.Monad.IO.Class (MonadIO (liftIO))
147−import Control.Monad.Trans.Class (MonadTrans(..))
148146import Data.Either (fromLeft, isLeft, isRight, fromRight)
149147import Data.Maybe (isJust, fromJust)
150148
@@ -248,24 +246,6 @@ foldrS f z xs =
248246 (toStreamK z)
249247 (toStreamK xs)
250248
251−-- | Right fold to a transformer monad. This is the most general right fold
252−-- function. 'foldrS' is a special case of 'foldrT', however 'foldrS'
253−-- implementation can be more efficient:
254−--
255−-- >>> foldrS = foldrT
256−--
257−-- >>> step f x xs = lift $ f x (runIdentityT xs)
258−-- >>> foldrM f z s = runIdentityT $ foldrT (step f) (lift z) s
259−--
260−-- 'foldrT' can be used to translate streamly streams to other transformer
261−-- monads e.g. to a different streaming type.
262−--
263−-- /Pre-release/
264−{-# INLINE foldrT #-}
265−foldrT :: (Monad m, Monad (s m), MonadTrans s)
266− => (a -> s m b -> s m b) -> s m b -> Stream m a -> s m b
267−foldrT f z s = D.foldrT f z (toStreamD s)
268−
269249------------------------------------------------------------------------------
270250-- Transformation by Mapping
271251------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Stream/Transformer.hs+25−3
@@ -8,7 +8,9 @@
88
99module Streamly.Internal.Data.Stream.Transformer
1010 (
11− liftInner
11+ foldrT
12+
13+ , liftInner
1214 , usingReaderT
1315 , runReaderT
1416 , evalStateT
@@ -17,16 +19,36 @@ module Streamly.Internal.Data.Stream.Transformer
1719 )
1820where
1921
22+import Control.Monad.Trans.Class (MonadTrans)
2023import Control.Monad.Trans.Reader (ReaderT)
2124import Control.Monad.Trans.State.Strict (StateT)
22−import Control.Monad.Trans.Class (MonadTrans(..))
2325import Streamly.Internal.Data.Stream.Type (Stream, fromStreamD, toStreamD)
2426
2527import qualified Streamly.Internal.Data.Stream.StreamD.Transformer as D
2628
2729-- $setup
2830-- >>> :m
29−-- >>> import Streamly.Internal.Data.Stream as Stream
31+-- >>> import Control.Monad.Trans (lift)
32+-- >>> import Control.Monad.Trans.Identity (runIdentityT)
33+-- >>> import qualified Streamly.Internal.Data.Stream as Stream
34+
35+-- | Right fold to a transformer monad. This is the most general right fold
36+-- function. 'foldrS' is a special case of 'foldrT', however 'foldrS'
37+-- implementation can be more efficient:
38+--
39+-- >>> foldrS = Stream.foldrT
40+--
41+-- >>> step f x xs = lift $ f x (runIdentityT xs)
42+-- >>> foldrM f z s = runIdentityT $ Stream.foldrT (step f) (lift z) s
43+--
44+-- 'foldrT' can be used to translate streamly streams to other transformer
45+-- monads e.g. to a different streaming type.
46+--
47+-- /Pre-release/
48+{-# INLINE foldrT #-}
49+foldrT :: (Monad m, Monad (s m), MonadTrans s)
50+ => (a -> s m b -> s m b) -> s m b -> Stream m a -> s m b
51+foldrT f z s = D.foldrT f z (toStreamD s)
3052
3153------------------------------------------------------------------------------
3254-- Add and remove a monad transformer