on master help sign in
Add foldIterateM
commitb6253327faa46b5ebfac79604e9c1d334c24d3f9 authorAdithya Kumar <adithya@composewell.com> dateSat 6 Mar 2021, 06:00 (6 years ago) parentad9308e
2 files changed+52−12
src/Streamly/Internal/Data/Stream/IsStream/Nesting.hs+7−12 src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+45
src/Streamly/Internal/Data/Stream/IsStream/Nesting.hs+7−12
@@ -130,7 +130,7 @@ module Streamly.Internal.Data.Stream.IsStream.Nesting
130130 , foldMany
131131 , foldManyPost
132132 , foldSequence
133− , foldIterate
133+ , foldIterateM
134134
135135 -- ** Parsing
136136 -- | Apply parsers on a stream.
@@ -1009,9 +1009,9 @@ foldSequence _f _m = undefined
10091009--
10101010-- @
10111011-- > import Data.Monoid (Sum(..))
1012−-- > f x = Fold.take 2 (Fold.sconcat x)
1012+-- > f x = return (Fold.take 2 (Fold.sconcat x))
10131013-- > s = Stream.map Sum $ Stream.fromList [1..10]
1014−-- > Stream.toList $ Stream.map getSum $ Stream.foldIterate f 0 s
1014+-- > Stream.toList $ Stream.map getSum $ Stream.foldIterateM f 0 s
10151015-- [3,10,21,36,55,55]
10161016--
10171017-- @
@@ -1021,15 +1021,10 @@ foldSequence _f _m = undefined
10211021--
10221022-- /Pre-release/
10231023--
1024−{-# INLINE foldIterate #-}
1025−foldIterate
1026− :: -- (IsStream t, Monad m) =>
1027− (b -> Fold m a b)
1028− -> b
1029− -> t m a
1030− -> t m b
1031−foldIterate _f _i _m = undefined
1032−-- D.fromStreamD $ D.foldIterate f i (D.toStreamD m)
1024+{-# INLINE foldIterateM #-}
1025+foldIterateM ::
1026+ (IsStream t, Monad m) => (b -> m (Fold m a b)) -> b -> t m a -> t m b
1027+foldIterateM f i m = D.fromStreamD $ D.foldIterateM f i (D.toStreamD m)
10331028
10341029------------------------------------------------------------------------------
10351030-- Parsing
src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+45
@@ -112,6 +112,7 @@ module Streamly.Internal.Data.Stream.StreamD.Nesting
112112 -- ** Folding
113113 -- | Apply folds on a stream.
114114 , foldMany
115+ , foldIterateM
115116
116117 -- ** Parsing
117118 -- | Parsing is opposite to flattening. 'parseMany' is dual to concatMap or
@@ -957,6 +958,50 @@ gintercalate
957958 return $ Yield x (ICALFirstInner s1 s2 i1 i2)
958959 -}
959960
961+------------------------------------------------------------------------------
962+-- Folding
963+------------------------------------------------------------------------------
964+
965+{-# ANN type FIterState Fuse #-}
966+data FIterState s f m a b
967+ = FIterInit s f
968+ | forall fs. FIterStream s (fs -> a -> m (FL.Step fs b)) fs (fs -> m b)
969+ | FIterYield b (FIterState s f m a b)
970+ | FIterStop
971+
972+{-# INLINE_NORMAL foldIterateM #-}
973+foldIterateM ::
974+ Monad m => (b -> m (FL.Fold m a b)) -> b -> Stream m a -> Stream m b
975+foldIterateM func seed0 (Stream step state) =
976+ Stream stepOuter (FIterInit state seed0)
977+
978+ where
979+
980+ {-# INLINE iterStep #-}
981+ iterStep from st fstep extract = do
982+ res <- from
983+ return
984+ $ Skip
985+ $ case res of
986+ FL.Partial fs -> FIterStream st fstep fs extract
987+ FL.Done fb -> FIterYield fb $ FIterInit st fb
988+
989+ {-# INLINE_LATE stepOuter #-}
990+ stepOuter _ (FIterInit st seed) = do
991+ (FL.Fold fstep initial extract) <- func seed
992+ iterStep initial st fstep extract
993+ stepOuter gst (FIterStream st fstep fs extract) = do
994+ r <- step (adaptState gst) st
995+ case r of
996+ Yield x s -> do
997+ iterStep (fstep fs x) s fstep extract
998+ Skip s -> return $ Skip $ FIterStream s fstep fs extract
999+ Stop -> do
1000+ b <- extract fs
1001+ return $ Skip $ FIterYield b FIterStop
1002+ stepOuter _ (FIterYield a next) = return $ Yield a next
1003+ stepOuter _ FIterStop = return Stop
1004+
9601005------------------------------------------------------------------------------
9611006-- Parsing
9621007------------------------------------------------------------------------------