on master help sign in
Add foldIterateM
b625332Adithya Kumar
src/Streamly/Internal/Data/Stream/IsStream/Nesting.hs+7−12
@@ -130,7 +130,7 @@ module Streamly.Internal.Data.Stream.IsStream.Nesting
130 , foldMany
130 , foldMany
131 , foldManyPost
131 , foldManyPost
132 , foldSequence
132 , foldSequence
133− , foldIterate
133+ , foldIterateM
134
134
135 -- ** Parsing
135 -- ** Parsing
136 -- | Apply parsers on a stream.
136 -- | Apply parsers on a stream.
@@ -1009,9 +1009,9 @@ foldSequence _f _m = undefined
1009--
1009--
1010-- @
1010-- @
1011-- > import Data.Monoid (Sum(..))
1011-- > import Data.Monoid (Sum(..))
1012−-- > f x = Fold.take 2 (Fold.sconcat x)
1012+-- > f x = return (Fold.take 2 (Fold.sconcat x))
1013-- > s = Stream.map Sum $ Stream.fromList [1..10]
1013-- > 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
1015-- [3,10,21,36,55,55]
1015-- [3,10,21,36,55,55]
1016--
1016--
1017-- @
1017-- @
@@ -1021,15 +1021,10 @@ foldSequence _f _m = undefined
1021--
1021--
1022-- /Pre-release/
1022-- /Pre-release/
1023--
1023--
1024−{-# INLINE foldIterate #-}
1024+{-# INLINE foldIterateM #-}
1025−foldIterate
1025+foldIterateM ::
1026− :: -- (IsStream t, Monad m) =>
1026+ (IsStream t, Monad m) => (b -> m (Fold m a b)) -> b -> t m a -> t m b
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)
1027+foldIterateM f i m = D.fromStreamD $ D.foldIterateM f i (D.toStreamD m)
1033
1028
1034------------------------------------------------------------------------------
1029------------------------------------------------------------------------------
1035-- Parsing
1030-- Parsing
src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+45
@@ -112,6 +112,7 @@ module Streamly.Internal.Data.Stream.StreamD.Nesting
112 -- ** Folding
112 -- ** Folding
113 -- | Apply folds on a stream.
113 -- | Apply folds on a stream.
114 , foldMany
114 , foldMany
115+ , foldIterateM
115
116
116 -- ** Parsing
117 -- ** Parsing
117 -- | Parsing is opposite to flattening. 'parseMany' is dual to concatMap or
118 -- | Parsing is opposite to flattening. 'parseMany' is dual to concatMap or
@@ -957,6 +958,50 @@ gintercalate
957 return $ Yield x (ICALFirstInner s1 s2 i1 i2)
958 return $ Yield x (ICALFirstInner s1 s2 i1 i2)
958 -}
959 -}
959
960
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+
960------------------------------------------------------------------------------
1005------------------------------------------------------------------------------
961-- Parsing
1006-- Parsing
962------------------------------------------------------------------------------
1007------------------------------------------------------------------------------