@@ -236,6 +236,7 @@ module Streamly.Internal.Data.Fold
236 , chunksBetween
236 , chunksBetween
238 -- ** Nesting
238 -- ** Nesting
239 , concatSequence
240 , concatSequence
240 , concatMap
241 , concatMap
@@ -257,6 +258,8 @@ module Streamly.Internal.Data.Fold
260import Data.Bifunctor (first)
263import Data.Bifunctor (first)
261import Data.Either (isLeft, isRight, fromLeft, fromRight)
264import Data.Either (isLeft, isRight, fromLeft, fromRight)
262import Data.Functor.Identity (Identity(..))
265import Data.Functor.Identity (Identity(..))
@@ -266,6 +269,7 @@ import Data.Maybe (isJust, fromJust)
266import Streamly.Internal.Data.Either.Strict
269import Streamly.Internal.Data.Either.Strict
267 (Either'(..), fromLeft', fromRight', isLeft', isRight')
270 (Either'(..), fromLeft', fromRight', isLeft', isRight')
268import Streamly.Internal.Data.Pipe.Type (Pipe (..), PipeState(..))
271import Streamly.Internal.Data.Pipe.Type (Pipe (..), PipeState(..))
272+import Streamly.Internal.Data.Unfold.Type (Unfold(..))
269import Streamly.Internal.Data.Tuple.Strict (Tuple'(..), Tuple3'(..))
273import Streamly.Internal.Data.Tuple.Strict (Tuple'(..), Tuple3'(..))
270import Streamly.Internal.Data.Stream.Serial (SerialT(..))
274import Streamly.Internal.Data.Stream.Serial (SerialT(..))
@@ -273,6 +277,7 @@ import qualified Data.IntSet as IntSet
273import qualified Data.Map.Strict as Map
277import qualified Data.Map.Strict as Map
274import qualified Data.Set as Set
278import qualified Data.Set as Set
275import qualified Streamly.Internal.Data.Pipe.Type as Pipe
279import qualified Streamly.Internal.Data.Pipe.Type as Pipe
280+import qualified Streamly.Internal.Data.Stream.StreamD.Type as StreamD
276-- import qualified Streamly.Internal.Data.Stream.IsStream.Enumeration as Stream
281-- import qualified Streamly.Internal.Data.Stream.IsStream.Enumeration as Stream
277import qualified Prelude
282import qualified Prelude
@@ -1921,3 +1926,36 @@ toStream = fmap SerialT toStreamK
1921{-# INLINE toStreamRev #-}
1926{-# INLINE toStreamRev #-}
1922toStreamRev :: Monad m => Fold m a (SerialT n a)
1927toStreamRev :: Monad m => Fold m a (SerialT n a)
1923toStreamRev = fmap SerialT toStreamKRev
1928toStreamRev = fmap SerialT toStreamKRev
1930+-- XXX This does not fuse. It contains a recursive step function. We will need
1931+-- a Skip input constructor in the fold type to make it fuse.
1933+-- | Unfold and flatten the input stream of a fold.
1936+-- Stream.fold (unfoldMany u f) = Stream.fold f . Stream.unfoldMany u
1940+{-# INLINE unfoldMany #-}
1941+unfoldMany :: Monad m => Unfold m a b -> Fold m b c -> Fold m a c
1942+unfoldMany (Unfold ustep inject) (Fold fstep initial extract) =
1943+ Fold consume initial extract
1947+ {-# INLINE produce #-}
1951+ StreamD.Yield b us1 -> do
1954+ Partial fs1 -> produce fs1 us1
1955+ -- XXX What to do with the remaining stream?
1956+ Done c -> return $ Done c
1957+ StreamD.Skip us1 -> produce fs us1
1958+ StreamD.Stop -> return $ Partial fs
1960+ {-# INLINE_LATE consume #-}
1961+ consume s a = inject a >>= produce s