on master help sign in
Add reduceIterateBfs
e23fed4Harendra Kumar
core/src/Streamly/Internal/Data/Stream/Reduce.hs+11−1
@@ -33,6 +33,7 @@ module Streamly.Internal.Data.Stream.Reduce
33 , foldSequence
33 , foldSequence
34 , foldIterateM
34 , foldIterateM
35 , refoldIterateM
35 , refoldIterateM
36+ , reduceIterateBfs
36
37
37 -- ** Chunking
38 -- ** Chunking
38 -- | Element unaware grouping.
39 -- | Element unaware grouping.
@@ -60,7 +61,7 @@ import Control.Monad.IO.Class (MonadIO(..))
60import Streamly.Internal.Data.Array.Type (Array)
61import Streamly.Internal.Data.Array.Type (Array)
61import Streamly.Internal.Data.Fold.Type (Fold (..))
62import Streamly.Internal.Data.Fold.Type (Fold (..))
62import Streamly.Internal.Data.Parser (Parser (..))
63import Streamly.Internal.Data.Parser (Parser (..))
63−import Streamly.Internal.Data.Parser.ParserD (ParseError)
64+import Streamly.Internal.Data.Parser.ParserD (ParseError)
64import Streamly.Internal.Data.Refold.Type (Refold (..))
65import Streamly.Internal.Data.Refold.Type (Refold (..))
65import Streamly.Internal.Data.Stream.Bottom (foldManyPost)
66import Streamly.Internal.Data.Stream.Bottom (foldManyPost)
66import Streamly.Internal.Data.Stream.Type (Stream, fromStreamD, toStreamD)
67import Streamly.Internal.Data.Stream.Type (Stream, fromStreamD, toStreamD)
@@ -211,6 +212,15 @@ refoldIterateM :: Monad m =>
211 Refold m b a b -> m b -> Stream m a -> Stream m b
212 Refold m b a b -> m b -> Stream m a -> Stream m b
212refoldIterateM c i m = fromStreamD $ D.refoldIterateM c i (toStreamD m)
213refoldIterateM c i m = fromStreamD $ D.refoldIterateM c i (toStreamD m)
213
214
215+-- | Binary BFS style reduce, folds a level entirely using the supplied fold
216+-- function, collecting the outputs as next level of the tree, then repeats the
217+-- same process on the next level. The last elements of a previously folded
218+-- level are folded first.
219+{-# INLINE reduceIterateBfs #-}
220+reduceIterateBfs :: Monad m =>
221+ (a -> a -> m a) -> Stream m a -> m (Maybe a)
222+reduceIterateBfs f stream = D.reduceIterateBfs f (toStreamD stream)
223+
214------------------------------------------------------------------------------
224------------------------------------------------------------------------------
215-- Splitting
225-- Splitting
216------------------------------------------------------------------------------
226------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Stream/StreamD/Type.hs+64
@@ -89,6 +89,7 @@ module Streamly.Internal.Data.Stream.StreamD.Type
89 , concatMapM
89 , concatMapM
90 , concatEffect
90 , concatEffect
91
91
92+ -- * Expanding trees top down
92 , unfoldIterateDfs
93 , unfoldIterateDfs
93 , unfoldIterateBfs
94 , unfoldIterateBfs
94 , unfoldIterateBfsRev
95 , unfoldIterateBfsRev
@@ -105,6 +106,10 @@ module Streamly.Internal.Data.Stream.StreamD.Type
105 , chunksOf
106 , chunksOf
106
107
107 , refoldMany
108 , refoldMany
109+
110+ -- * Folding trees bottom up
111+ , reduceIterateBfs
112+ , foldIterateBfs
108 )
113 )
109where
114where
110
115
@@ -894,6 +899,10 @@ instance Monad m => Monad (Stream m) where
894 (>>) = (*>)
899 (>>) = (*>)
895-}
900-}
896
901
902+------------------------------------------------------------------------------
903+-- Traversing a tree top down
904+------------------------------------------------------------------------------
905+
897-- | Generate a stream from an initial state, scan and concat the stream,
906-- | Generate a stream from an initial state, scan and concat the stream,
898-- generate a stream again from the final state of the previous scan and repeat
907-- generate a stream again from the final state of the previous scan and repeat
899-- the process.
908-- the process.
@@ -1130,6 +1139,61 @@ unfoldIterateBfs (Unfold istep inject) (Stream ostep ost) =
1130 (y:ys) -> return $ Skip (IterateUnfoldBFSInner y ys [])
1139 (y:ys) -> return $ Skip (IterateUnfoldBFSInner y ys [])
1131 [] -> return Stop
1140 [] -> return Stop
1132
1141
1142+------------------------------------------------------------------------------
1143+-- Folding a tree bottom up
1144+------------------------------------------------------------------------------
1145+
1146+-- | Binary BFS style reduce, folds a level entirely, before starting to fold
1147+-- the next level. The last elements of a previously folded level are folded
1148+-- first.
1149+{-# INLINE_NORMAL reduceIterateBfs #-}
1150+reduceIterateBfs :: Monad m =>
1151+ (a -> a -> m a) -> Stream m a -> m (Maybe a)
1152+reduceIterateBfs f (Stream step state) = go SPEC state [] Nothing
1153+
1154+ where
1155+
1156+ go _ st xs Nothing = do
1157+ r <- step defState st
1158+ case r of
1159+ Yield x1 s -> go SPEC s xs (Just x1)
1160+ Skip s -> go SPEC s xs Nothing
1161+ Stop ->
1162+ case xs of
1163+ [] -> return Nothing
1164+ _ -> goBuf SPEC xs []
1165+ go _ st xs (Just x1) = do
1166+ r2 <- step defState st
1167+ case r2 of
1168+ Yield x2 s -> do
1169+ x <- f x1 x2
1170+ go SPEC s (x:xs) Nothing
1171+ Skip s -> go SPEC s xs (Just x1)
1172+ Stop ->
1173+ case xs of
1174+ [] -> return (Just x1)
1175+ _ -> goBuf SPEC (x1:xs) []
1176+
1177+ goBuf _ [] ys = goBuf SPEC ys []
1178+ goBuf _ [x1] ys = do
1179+ case ys of
1180+ [] -> return (Just x1)
1181+ (x2:xs) -> do
1182+ y <- f x1 x2
1183+ goBuf SPEC xs [y]
1184+ goBuf _ (x1:x2:xs) ys = do
1185+ y <- f x1 x2
1186+ goBuf SPEC xs (y:ys)
1187+
1188+-- | N-Ary BFS style iterative fold, if the input stream finished before the
1189+-- fold then it returns Left otherwise Right. If the fold returns Left we
1190+-- terminate.
1191+--
1192+-- /Unimplemented/
1193+foldIterateBfs ::
1194+ Fold m a (Either a a) -> Stream m a -> m (Maybe a)
1195+foldIterateBfs = undefined
1196+
1133------------------------------------------------------------------------------
1197------------------------------------------------------------------------------
1134-- Grouping/Splitting
1198-- Grouping/Splitting
1135------------------------------------------------------------------------------
1199------------------------------------------------------------------------------