on master help sign in
Add reduceIterateBfs
commite23fed4ba18fc5d44cf73709378b89f20ba00759 authorHarendra Kumar <harendra@composewell.com> dateSat 14 Jan 2023, 18:17 (4 years ago) parent96a8bd0
2 files changed+75−1
core/src/Streamly/Internal/Data/Stream/Reduce.hs+11−1 core/src/Streamly/Internal/Data/Stream/StreamD/Type.hs+64
core/src/Streamly/Internal/Data/Stream/Reduce.hs+11−1
@@ -33,6 +33,7 @@ module Streamly.Internal.Data.Stream.Reduce
3333 , foldSequence
3434 , foldIterateM
3535 , refoldIterateM
36+ , reduceIterateBfs
3637
3738 -- ** Chunking
3839 -- | Element unaware grouping.
@@ -60,7 +61,7 @@ import Control.Monad.IO.Class (MonadIO(..))
6061import Streamly.Internal.Data.Array.Type (Array)
6162import Streamly.Internal.Data.Fold.Type (Fold (..))
6263import Streamly.Internal.Data.Parser (Parser (..))
63−import Streamly.Internal.Data.Parser.ParserD (ParseError)
64+import Streamly.Internal.Data.Parser.ParserD (ParseError)
6465import Streamly.Internal.Data.Refold.Type (Refold (..))
6566import Streamly.Internal.Data.Stream.Bottom (foldManyPost)
6667import Streamly.Internal.Data.Stream.Type (Stream, fromStreamD, toStreamD)
@@ -211,6 +212,15 @@ refoldIterateM :: Monad m =>
211212 Refold m b a b -> m b -> Stream m a -> Stream m b
212213refoldIterateM c i m = fromStreamD $ D.refoldIterateM c i (toStreamD m)
213214
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+
214224------------------------------------------------------------------------------
215225-- Splitting
216226------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Stream/StreamD/Type.hs+64
@@ -89,6 +89,7 @@ module Streamly.Internal.Data.Stream.StreamD.Type
8989 , concatMapM
9090 , concatEffect
9191
92+ -- * Expanding trees top down
9293 , unfoldIterateDfs
9394 , unfoldIterateBfs
9495 , unfoldIterateBfsRev
@@ -105,6 +106,10 @@ module Streamly.Internal.Data.Stream.StreamD.Type
105106 , chunksOf
106107
107108 , refoldMany
109+
110+ -- * Folding trees bottom up
111+ , reduceIterateBfs
112+ , foldIterateBfs
108113 )
109114where
110115
@@ -894,6 +899,10 @@ instance Monad m => Monad (Stream m) where
894899 (>>) = (*>)
895900-}
896901
902+------------------------------------------------------------------------------
903+-- Traversing a tree top down
904+------------------------------------------------------------------------------
905+
897906-- | Generate a stream from an initial state, scan and concat the stream,
898907-- generate a stream again from the final state of the previous scan and repeat
899908-- the process.
@@ -1130,6 +1139,61 @@ unfoldIterateBfs (Unfold istep inject) (Stream ostep ost) =
11301139 (y:ys) -> return $ Skip (IterateUnfoldBFSInner y ys [])
11311140 [] -> return Stop
11321141
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+
11331197------------------------------------------------------------------------------
11341198-- Grouping/Splitting
11351199------------------------------------------------------------------------------