@@ -123,14 +123,21 @@ module Streamly.Internal.Data.Stream.Type
123 , foldManyPost
123 , foldManyPost
124 , groupsOf
124 , groupsOf
125 , refoldMany
125 , refoldMany
127 -- * Fold Iterate
128 -- * Fold Iterate
128 , reduceIterateBfs
129 , reduceIterateBfs
129 , foldIterateBfs
130 , foldIterateBfs
131 -- * Multi-stream folds
135 -- * Multi-stream folds
@@ -162,6 +169,7 @@ import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
162import Streamly.Internal.Data.Refold.Type (Refold(..))
169import Streamly.Internal.Data.Refold.Type (Refold(..))
163import Streamly.Internal.Data.Stream.Step (Step (..))
170import Streamly.Internal.Data.Stream.Step (Step (..))
164import Streamly.Internal.Data.SVar.Type (State, adaptState, defState)
171import Streamly.Internal.Data.SVar.Type (State, adaptState, defState)
172+import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
165import Streamly.Internal.Data.Unfold.Type (Unfold(..))
173import Streamly.Internal.Data.Unfold.Type (Unfold(..))
167import qualified Streamly.Internal.Data.Fold.Type as FL hiding (foldr)
175import qualified Streamly.Internal.Data.Fold.Type as FL hiding (foldr)
@@ -1974,6 +1982,90 @@ refoldMany (Refold fstep inject extract) action (Stream step state) =
1974 step' _ (FoldManyYield b next) = return $ Yield b next
1982 step' _ (FoldManyYield b next) = return $ Yield b next
1975 step' _ FoldManyDone = return Stop
1983 step' _ FoldManyDone = return Stop
1985+{-# ANN type CIterState Fuse #-}
1986+data CIterState s f fs b
1988+ | CIterConsume s fs
1989+ | CIterYield b (CIterState s f fs b)
1992+-- | Like 'foldIterateM' but using the 'Refold' type instead. This could be
1993+-- much more efficient due to stream fusion.
1996+{-# INLINE_NORMAL refoldIterateM #-}
1998+ Monad m => Refold m b a b -> m b -> Stream m a -> Stream m b
1999+refoldIterateM (Refold fstep finject fextract) initial (Stream step state) =
2000+ Stream stepOuter (CIterInit state initial)
2004+ {-# INLINE iterStep #-}
2005+ iterStep st action = do
2010+ FL.Partial fs -> CIterConsume st fs
2011+ FL.Done fb -> CIterYield fb $ CIterInit st (return fb)
2013+ {-# INLINE_LATE stepOuter #-}
2014+ stepOuter _ (CIterInit st action) = do
2015+ iterStep st (action >>= finject)
2016+ stepOuter gst (CIterConsume st fs) = do
2017+ r <- step (adaptState gst) st
2019+ Yield x s -> iterStep s (fstep fs x)
2020+ Skip s -> return $ Skip $ CIterConsume s fs
2023+ return $ Skip $ CIterYield b CIterStop
2024+ stepOuter _ (CIterYield a next) = return $ Yield a next
2025+ stepOuter _ CIterStop = return Stop
2027+-- | The refold @indexerBy f n@ takes an (index, len) tuple as initial input,
2028+-- and returns @(index + len + n, b)@ as output where @b@ is the output of the
2030+{-# INLINE indexerBy #-}
2031+indexerBy :: Monad m =>
2032+ Fold m a Int -> Int -> Refold m (Int, Int) a (Int, Int)
2033+indexerBy (Fold step1 initial1 extract1 _final) n =
2034+ Refold step inject extract
2038+ inject (i, len) = do
2041+ FL.Partial s -> FL.Partial $ Tuple' (i + len + n) s
2042+ FL.Done l -> FL.Done (i, l)
2044+ step (Tuple' i s) x = do
2047+ FL.Partial s1 -> FL.Partial $ Tuple' i s1
2048+ FL.Done len -> FL.Done (i, len)
2050+ extract (Tuple' i s) = (i,) <$> extract1 s
2052+-- | Like 'splitOnSuffix' but generates a stream of (index, len) tuples marking
2053+-- the places where the predicate matches in the stream.
2056+{-# INLINE indexOnSuffix #-}
2057+indexOnSuffix :: Monad m =>
2058+ (a -> Bool) -> Stream m a -> Stream m (Int, Int)
2059+indexOnSuffix predicate =
2060+ -- Scan the stream with the given refold
2062+ (indexerBy (FL.takeEndBy_ predicate FL.length) 1)
2065+{-# DEPRECATED sliceOnSuffix "Please use indexOnSuffix instead." #-}
2066+sliceOnSuffix :: Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int)
2067+sliceOnSuffix = indexOnSuffix
1977------------------------------------------------------------------------------
2069------------------------------------------------------------------------------
1978-- Stream with a cross product style monad instance
2070-- Stream with a cross product style monad instance
1979------------------------------------------------------------------------------
2071------------------------------------------------------------------------------