@@ -271,7 +271,10 @@ module Streamly.Internal.Prelude
271 , intercalateSuffix
271 , intercalateSuffix
272 , interpose
272 , interpose
273 , interposeSuffix
273 , interposeSuffix
274+ , concatMapIterateWith
274 , concatMapTreeWith
275 , concatMapTreeWith
277+ , concatMapTreeYieldLeavesWith
276 -- -- ** Breaking
279 -- -- ** Breaking
@@ -2581,6 +2584,23 @@ interposeSuffix x unf str =
2581-- Flattening Trees
2584-- Flattening Trees
2582------------------------------------------------------------------------------
2585------------------------------------------------------------------------------
2587+-- | Like 'iterateM' but using a stream generator function.
2591+{-# INLINE concatMapIterateWith #-}
2592+concatMapIterateWith
2594+ => (forall c. t m c -> t m c -> t m c)
2598+concatMapIterateWith combine f xs = concatMapWith combine go xs
2600+ go x = yield x `combine` concatMapWith combine go (f x)
2602+-- concatMapIterateLeftsWith
2584-- | Traverse a forest with recursive tree structures whose non-leaf nodes are
2604-- | Traverse a forest with recursive tree structures whose non-leaf nodes are
2585-- of type @a@ and leaf nodes are of type @b@, flattening all the trees into
2605-- of type @a@ and leaf nodes are of type @b@, flattening all the trees into
2586-- streams and combining the streams into a single stream consisting of both
2606-- streams and combining the streams into a single stream consisting of both
@@ -2594,6 +2614,13 @@ interposeSuffix x unf str =
2594-- Traversing a directory tree recursively is a canonical use case of
2614-- Traversing a directory tree recursively is a canonical use case of
2595-- 'concatMapTreeWith'.
2615-- 'concatMapTreeWith'.
2618+-- concatMapTreeWith combine f xs = concatMapIterateWith combine g xs
2620+-- g (Left tree) = f tree
2621+-- g (Right leaf) = nil
2597-- /Internal/
2624-- /Internal/
2599{-# INLINE concatMapTreeWith #-}
2626{-# INLINE concatMapTreeWith #-}
@@ -2601,7 +2628,7 @@ concatMapTreeWith
2601 :: IsStream t
2628 :: IsStream t
2602 => (forall c. t m c -> t m c -> t m c)
2629 => (forall c. t m c -> t m c -> t m c)
2603 -> (a -> t m (Either a b))
2630 -> (a -> t m (Either a b))
2604− -> t m (Either a b)
2631+ -> t m (Either a b) -- Should be t m a?
2605 -> t m (Either a b)
2632 -> t m (Either a b)
2606concatMapTreeWith combine f xs = concatMapWith combine go xs
2633concatMapTreeWith combine f xs = concatMapWith combine go xs
@@ -2610,11 +2637,15 @@ concatMapTreeWith combine f xs = concatMapWith combine go xs
2612-- | Like concatMapTreeWith but produces only stream of leaf elements.
2639-- | Like concatMapTreeWith but produces only stream of leaf elements.
2640+-- On an either stream, iterate lefts but yield only rights.
2614−{-# INLINE concatMapLeavesWith #-}
2642+-- concatMapEitherYieldRightsWith combine f xs =
2643+-- catRights $ concatMapTreeWith combine f xs
2645+{-# INLINE concatMapEitherYieldRightsWith #-}
2615−concatMapLeavesWith :: (IsStream t, MonadAsync m)
2646+concatMapEitherYieldRightsWith :: (IsStream t, MonadAsync m)
2616 => _ -> (a -> t m (Either a b)) -> t m (Either a b) -> t m b
2647 => _ -> (a -> t m (Either a b)) -> t m (Either a b) -> t m b
2617−concatMapLeavesWith combine f xs = undefined
2648+concatMapEitherYieldRightsWith combine f xs = undefined
@@ -2622,6 +2653,7 @@ concatMapLeavesWith combine f xs = undefined
2622concatUnfoldTree :: (IsStream t, MonadAsync m)
2653concatUnfoldTree :: (IsStream t, MonadAsync m)
2623 => Unfold m a (Either a b) -> t m (Either a b) -> t m (Either a b)
2654 => Unfold m a (Either a b) -> t m (Either a b) -> t m (Either a b)
2624concatUnfoldTree unf xs = undefined
2655concatUnfoldTree unf xs = undefined
2626------------------------------------------------------------------------------
2658------------------------------------------------------------------------------
2627-- Feedback loop
2659-- Feedback loop
@@ -2637,11 +2669,36 @@ concatUnfoldTree unf xs = undefined
2637-- on is the work queue. When evaluated it results in either a leaf element to
2669-- on is the work queue. When evaluated it results in either a leaf element to
2638-- yield or a tail stream to queue back to the work queue.
2670-- yield or a tail stream to queue back to the work queue.
2672+-- | Feedback a component of the output back to the input stream.
2640{-# INLINE concatMapLoopWith #-}
2676{-# INLINE concatMapLoopWith #-}
2641−concatMapLoopWith :: (IsStream t, MonadAsync m)
2678+ :: (IsStream t, MonadAsync m)
2679+ => (forall x. t m x -> t m x -> t m x)
2642− => _ -> (a -> t m (Either b c)) -> (b -> t m a) -> t m a -> t m c
2680+ -> (a -> t m (Either b c))
2681+ -> (b -> t m a) -- feedback function to feed b back into input
2643−concatMapLoopWith combine f xs = undefined
2684+concatMapLoopWith combine f fb xs =
2644−-}
2685+ concatMapWith combine go $ concatMapWith combine f xs
2687+ go (Left b) = concatMapLoopWith combine f fb $ fb b
2688+ go (Right c) = yield c
2690+-- Concat a stream of trees, generating only leaves.
2694+{-# INLINE concatMapTreeYieldLeavesWith #-}
2695+concatMapTreeYieldLeavesWith
2696+ :: (IsStream t, MonadAsync m)
2697+ => (forall x. t m x -> t m x -> t m x)
2698+ -> (a -> t m (Either a b))
2701+concatMapTreeYieldLeavesWith combine f = concatMapLoopWith combine f yield
2646------------------------------------------------------------------------------
2703------------------------------------------------------------------------------
2647-- Grouping/Splitting
2704-- Grouping/Splitting