on master help sign in
Add scanMany to Fold
a6f041cRanjeet Kumar Ranjan
benchmark/Streamly/Benchmark/Data/Fold.hs+4
@@ -373,6 +373,10 @@ o_1_space_serial_transformation value =
373 value
373 value
374 "fold-scan"
374 "fold-scan"
375 (S.fold $ FL.scan FL.sum FL.drain)
375 (S.fold $ FL.scan FL.sum FL.drain)
376+ , benchIOSink
377+ value
378+ "fold-scanMany"
379+ (S.fold $ FL.scanMany (FL.take 2 FL.drain) FL.drain)
376 , benchIOSink
380 , benchIOSink
377 value
381 value
378 "fold-postscan"
382 "fold-postscan"
core/src/Streamly/Internal/Data/Fold.hs+27−10
@@ -126,6 +126,7 @@ module Streamly.Internal.Data.Fold
126 --, lsequence
126 --, lsequence
127 , lmapM
127 , lmapM
128 , scan
128 , scan
129+ , scanMany
129 , postscan
130 , postscan
130 , indexed
131 , indexed
131
132
@@ -292,10 +293,9 @@ import qualified Data.IntSet as IntSet
292import qualified Data.Map.Strict as Map
293import qualified Data.Map.Strict as Map
293import qualified Data.Set as Set
294import qualified Data.Set as Set
294import qualified Streamly.Internal.Data.IsMap as IsMap
295import qualified Streamly.Internal.Data.IsMap as IsMap
296+import qualified Prelude
295import qualified Streamly.Internal.Data.Pipe.Type as Pipe
297import qualified Streamly.Internal.Data.Pipe.Type as Pipe
296import qualified Streamly.Internal.Data.Stream.StreamD.Type as StreamD
298import qualified Streamly.Internal.Data.Stream.StreamD.Type as StreamD
297−-- import qualified Streamly.Internal.Data.Stream.IsStream.Enumeration as Stream
298−import qualified Prelude
299
299
300import Prelude hiding
300import Prelude hiding
301 ( filter, foldl1, drop, dropWhile, take, takeWhile, zipWith
301 ( filter, foldl1, drop, dropWhile, take, takeWhile, zipWith
@@ -417,17 +417,13 @@ transform (Pipe pstep1 pstep2 pinitial) (Fold fstep finitial fextract) =
417
417
418 extract (Tuple' _ fs) = fextract fs
418 extract (Tuple' _ fs) = fextract fs
419
419
420−-- | Scan the input of a 'Fold' to change it in a stateful manner using another
421−-- 'Fold'.
422−-- /Pre-release/
423−{-# INLINE scan #-}
420+{-# INLINE scanWith #-}
424−scan :: Monad m => Fold m a b -> Fold m b c -> Fold m a c
421+scanWith :: Monad m => Bool -> Fold m a b -> Fold m b c -> Fold m a c
425−scan (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
422+scanWith isMany (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
426 Fold step initial extract
423 Fold step initial extract
427
424
428 where
425 where
429
426
430− -- XXX It can be moved out and used for both scan and postscan
431 {-# INLINE runStep #-}
427 {-# INLINE runStep #-}
432 runStep actionL sR = do
428 runStep actionL sR = do
433 rL <- actionL
429 rL <- actionL
@@ -435,7 +431,10 @@ scan (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
435 Done bL -> do
431 Done bL -> do
436 rR <- stepR sR bL
432 rR <- stepR sR bL
437 case rR of
433 case rR of
434+ Partial sR1 ->
435+ if isMany
436+ then runStep initialL sR1
438− Partial sR1 -> Done <$> extractR sR1
437+ else Done <$> extractR sR1
439 Done bR -> return $ Done bR
438 Done bR -> return $ Done bR
440 Partial sL -> do
439 Partial sL -> do
441 !b <- extractL sL
440 !b <- extractL sL
@@ -455,6 +454,24 @@ scan (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
455
454
456 extract = extractR . snd
455 extract = extractR . snd
457
456
457+-- | Scan the input of a 'Fold' to change it in a stateful manner using another
458+-- 'Fold'. The scan stops as soon as the fold terminates.
459+--
460+-- /Pre-release/
461+{-# INLINE scan #-}
462+scan :: Monad m => Fold m a b -> Fold m b c -> Fold m a c
463+scan = scanWith False
464+
465+-- XXX This does not fuse beacuse of the recursive step. Need to investigate.
466+--
467+-- | Scan the input of a 'Fold' to change it in a stateful manner using another
468+-- 'Fold'. The scan restarts with a fresh state if the fold terminates.
469+--
470+-- /Pre-release/
471+{-# INLINE scanMany #-}
472+scanMany :: Monad m => Fold m a b -> Fold m b c -> Fold m a c
473+scanMany = scanWith True
474+
458-- | Postscan the input of a 'Fold' to change it in a stateful manner using
475-- | Postscan the input of a 'Fold' to change it in a stateful manner using
459-- another 'Fold'.
476-- another 'Fold'.
460-- /Pre-release/
477-- /Pre-release/