on master help sign in
Add ScanMany for Stream
aa2b166Ranjeet Kumar Ranjan
core/src/Streamly/Internal/Data/Stream/StreamD/Transform.hs+25−15
@@ -39,6 +39,7 @@ module Streamly.Internal.Data.Stream.StreamD.Transform
39 -- * Scanning By 'Fold'
39 -- * Scanning By 'Fold'
40 , postscanOnce -- XXX rename to postscan
40 , postscanOnce -- XXX rename to postscan
41 , scanOnce -- XXX rename to scan
41 , scanOnce -- XXX rename to scan
42+ , scanMany
42
43
43 -- * Scanning
44 -- * Scanning
44 -- | Left scans. Stateful, mostly one-to-one maps.
45 -- | Left scans. Stateful, mostly one-to-one maps.
@@ -444,36 +445,45 @@ postscanOnce (FL.Fold fstep initial extract) (Stream sstep state) =
444 Stop -> return Stop
445 Stop -> return Stop
445 step _ ScanDone = return Stop
446 step _ ScanDone = return Stop
446
447
447−{-# INLINE scanOnce #-}
448+{-# INLINE scanWith #-}
448−scanOnce :: Monad m
449+scanWith :: Monad m
449− => FL.Fold m a b -> Stream m a -> Stream m b
450+ => Bool -> Fold m a b -> Stream m a -> Stream m b
450−scanOnce (FL.Fold fstep initial extract) (Stream sstep state) =
451+scanWith restart (Fold fstep initial extract) (Stream sstep state) =
451 Stream step (ScanInit state)
452 Stream step (ScanInit state)
452
453
453 where
454 where
454
455
455− {-# INLINE_LATE step #-}
456+ {-# INLINE runStep #-}
456− step _ (ScanInit st) = do
457+ runStep st action = do
457− res <- initial
458+ res <- action
458 case res of
459 case res of
459 FL.Partial fs -> do
460 FL.Partial fs -> do
460 !b <- extract fs
461 !b <- extract fs
461 return $ Yield b $ ScanDo st fs
462 return $ Yield b $ ScanDo st fs
463+ FL.Done b ->
464+ let next = if restart then ScanInit st else ScanDone
462− FL.Done b -> return $ Yield b ScanDone
465+ in return $ Yield b next
466+
467+ {-# INLINE_LATE step #-}
468+ step _ (ScanInit st) = runStep st initial
463 step gst (ScanDo st fs) = do
469 step gst (ScanDo st fs) = do
464 res <- sstep (adaptState gst) st
470 res <- sstep (adaptState gst) st
465 case res of
471 case res of
466− Yield x s -> do
467− r <- fstep fs x
472+ Yield x s -> runStep s (fstep fs x)
468− case r of
469− FL.Partial fs1 -> do
470− !b <- extract fs1
471− return $ Yield b $ ScanDo s fs1
472− FL.Done b -> return $ Yield b ScanDone
473 Skip s -> return $ Skip $ ScanDo s fs
473 Skip s -> return $ Skip $ ScanDo s fs
474 Stop -> return Stop
474 Stop -> return Stop
475 step _ ScanDone = return Stop
475 step _ ScanDone = return Stop
476
476
477+{-# INLINE scanOnce #-}
478+scanOnce :: Monad m
479+ => FL.Fold m a b -> Stream m a -> Stream m b
480+scanOnce = scanWith False
481+
482+{-# INLINE scanMany #-}
483+scanMany :: Monad m
484+ => FL.Fold m a b -> Stream m a -> Stream m b
485+scanMany = scanWith True
486+
477------------------------------------------------------------------------------
487------------------------------------------------------------------------------
478-- Scanning - Prescans
488-- Scanning - Prescans
479------------------------------------------------------------------------------
489------------------------------------------------------------------------------
src/Streamly/Internal/Data/Stream/IsStream/Transform.hs+9−1
@@ -38,6 +38,7 @@ module Streamly.Internal.Data.Stream.IsStream.Transform
38
38
39 -- * Scanning By 'Fold'
39 -- * Scanning By 'Fold'
40 , scan
40 , scan
41+ , scanMany
41 , postscan
42 , postscan
42
43
43 -- * Scanning
44 -- * Scanning
@@ -659,9 +660,16 @@ trace_ eff = fromStreamD . D.mapM (\x -> eff >> return x) . toStreamD
659-- @since 0.7.0
660-- @since 0.7.0
660{-# INLINE scan #-}
661{-# INLINE scan #-}
661scan :: (IsStream t, Monad m) => Fold m a b -> t m a -> t m b
662scan :: (IsStream t, Monad m) => Fold m a b -> t m a -> t m b
662−-- scan = P.scanOnce
663scan fld m = fromStreamD $ D.scanOnce fld $ toStreamD m
663scan fld m = fromStreamD $ D.scanOnce fld $ toStreamD m
664
664
665+-- | Like 'scan' but restarts scanning afresh when the scanning fold
666+-- terminates.
667+--
668+-- /Pre-release/
669+{-# INLINE scanMany #-}
670+scanMany :: (IsStream t, Monad m) => Fold m a b -> t m a -> t m b
671+scanMany fld m = fromStreamD $ D.scanMany fld $ toStreamD m
672+
665-- | Postscan a stream using the given monadic fold.
673-- | Postscan a stream using the given monadic fold.
666--
674--
667-- The following example extracts the input stream up to a point where the
675-- The following example extracts the input stream up to a point where the