@@ -82,6 +82,7 @@ module Streamly.Internal.Data.Unfold
85 , singleton
86 , singleton
86 , identity
87 , identity
@@ -158,6 +159,10 @@ import qualified Streamly.Internal.Data.Stream.StreamD as D
159-- | Map a function on the input argument of the 'Unfold'.
160-- | Map a function on the input argument of the 'Unfold'.
163+-- lmap f = concat (singleton f)
161-- /Internal/
166-- /Internal/
162{-# INLINE_NORMAL lmap #-}
167{-# INLINE_NORMAL lmap #-}
163lmap :: (a -> c) -> Unfold m c b -> Unfold m a b
168lmap :: (a -> c) -> Unfold m c b -> Unfold m a b
@@ -165,11 +170,18 @@ lmap f (Unfold ustep uinject) = Unfold ustep (uinject . f)
166-- | Map an action on the input argument of the 'Unfold'.
171-- | Map an action on the input argument of the 'Unfold'.
174+-- lmapM f = concat (singletonM f)
168-- /Internal/
177-- /Internal/
169{-# INLINE_NORMAL lmapM #-}
178{-# INLINE_NORMAL lmapM #-}
170lmapM :: Monad m => (a -> m c) -> Unfold m c b -> Unfold m a b
179lmapM :: Monad m => (a -> m c) -> Unfold m c b -> Unfold m a b
171lmapM f (Unfold ustep uinject) = Unfold ustep (\x -> f x >>= uinject)
180lmapM f (Unfold ustep uinject) = Unfold ustep (\x -> f x >>= uinject)
182+-- XXX change the signature to the following?
183+-- supply :: a -> Unfold m a b -> Unfold m Void b
173-- | Supply the seed to an unfold closing the input end of the unfold.
185-- | Supply the seed to an unfold closing the input end of the unfold.
175-- /Internal/
187-- /Internal/
@@ -178,6 +190,9 @@ lmapM f (Unfold ustep uinject) = Unfold ustep (\x -> f x >>= uinject)
178supply :: Unfold m a b -> a -> Unfold m Void b
190supply :: Unfold m a b -> a -> Unfold m Void b
179supply unf a = lmap (Prelude.const a) unf
191supply unf a = lmap (Prelude.const a) unf
193+-- XXX change the signature to the following?
194+-- supplyFirst :: a -> Unfold m (a, b) c -> Unfold m b c
181-- | Supply the first component of the tuple to an unfold that accepts a tuple
196-- | Supply the first component of the tuple to an unfold that accepts a tuple
182-- as a seed resulting in a fold that accepts the second component of the tuple
197-- as a seed resulting in a fold that accepts the second component of the tuple
183-- as a seed.
198-- as a seed.
@@ -188,6 +203,9 @@ supply unf a = lmap (Prelude.const a) unf
188supplyFirst :: Unfold m (a, b) c -> a -> Unfold m b c
203supplyFirst :: Unfold m (a, b) c -> a -> Unfold m b c
189supplyFirst unf a = lmap (a, ) unf
204supplyFirst unf a = lmap (a, ) unf
206+-- XXX change the signature to the following?
207+-- supplySecond :: b -> Unfold m (a, b) c -> Unfold m a c
191-- | Supply the second component of the tuple to an unfold that accepts a tuple
209-- | Supply the second component of the tuple to an unfold that accepts a tuple
192-- as a seed resulting in a fold that accepts the first component of the tuple
210-- as a seed resulting in a fold that accepts the first component of the tuple
193-- as a seed.
211-- as a seed.
@@ -376,25 +394,33 @@ effect eff = Unfold step inject
376 step True = eff >>= \r -> return $ Yield r False
394 step True = eff >>= \r -> return $ Yield r False
377 step False = return Stop
395 step False = return Stop
397+-- XXX change it to yieldM or change yieldM in Prelude to singletonM
379-- | Lift a monadic function into an unfold generating a singleton stream.
399-- | Lift a monadic function into an unfold generating a singleton stream.
381−{-# INLINE singleton #-}
401+{-# INLINE singletonM #-}
382−singleton :: Monad m => (a -> m b) -> Unfold m a b
402+singletonM :: Monad m => (a -> m b) -> Unfold m a b
383−singleton f = Unfold step inject
403+singletonM f = Unfold step inject
385 inject x = return $ Just x
405 inject x = return $ Just x
386 {-# INLINE_LATE step #-}
406 {-# INLINE_LATE step #-}
387 step (Just x) = f x >>= \r -> return $ Yield r Nothing
407 step (Just x) = f x >>= \r -> return $ Yield r Nothing
388 step Nothing = return Stop
408 step Nothing = return Stop
410+-- | Lift a pure function into an unfold generating a singleton stream.
412+{-# INLINE singleton #-}
413+singleton :: Monad m => (a -> b) -> Unfold m a b
414+singleton f = singletonM $ return . f
390-- | Identity unfold. Generates a singleton stream with the seed as the only
416-- | Identity unfold. Generates a singleton stream with the seed as the only
391-- element in the stream.
417-- element in the stream.
393−-- > identity = singleton return
419+-- > identity = singletonM return
395{-# INLINE identity #-}
421{-# INLINE identity #-}
396identity :: Monad m => Unfold m a a
422identity :: Monad m => Unfold m a a
397−identity = singleton return
423+identity = singletonM return
399const :: Monad m => m b -> Unfold m a b
425const :: Monad m => m b -> Unfold m a b
400const m = Unfold step inject
426const m = Unfold step inject
@@ -570,6 +596,11 @@ zipWith f = zipWithM (\a b -> return (f a b))
571data ConcatState s1 s2 = ConcatOuter s1 | ConcatInner s1 s2
597data ConcatState s1 s2 = ConcatOuter s1 | ConcatInner s1 s2
599+-- | Apply the second unfold to each output element of the first unfold and
600+-- flatten the output in a single stream.
573{-# INLINE_NORMAL concat #-}
604{-# INLINE_NORMAL concat #-}
574concat :: Monad m => Unfold m a b -> Unfold m b c -> Unfold m a c
605concat :: Monad m => Unfold m a b -> Unfold m b c -> Unfold m a c
575concat (Unfold step1 inject1) (Unfold step2 inject2) = Unfold step inject
606concat (Unfold step1 inject1) (Unfold step2 inject2) = Unfold step inject
@@ -598,6 +629,9 @@ concat (Unfold step1 inject1) (Unfold step2 inject2) = Unfold step inject
598data OuterProductState s1 s2 sy x y =
629data OuterProductState s1 s2 sy x y =
599 OuterProductOuter s1 y | OuterProductInner s1 sy s2 x
630 OuterProductOuter s1 y | OuterProductInner s1 sy s2 x
632+-- | Create an outer product (vector product or cartesian product) of the
633+-- output streams of two unfolds.
601{-# INLINE_NORMAL outerProduct #-}
635{-# INLINE_NORMAL outerProduct #-}
602outerProduct :: Monad m
636outerProduct :: Monad m
603 => Unfold m a b -> Unfold m c d -> Unfold m (a, c) (b, d)
637 => Unfold m a b -> Unfold m c d -> Unfold m (a, c) (b, d)
@@ -628,6 +662,9 @@ outerProduct (Unfold step1 inject1) (Unfold step2 inject2) = Unfold step inject
629data ConcatMapState s1 s2 = ConcatMapOuter s1 | ConcatMapInner s1 s2
663data ConcatMapState s1 s2 = ConcatMapOuter s1 | ConcatMapInner s1 s2
665+-- | Map an unfold generating action to each element of an unfold and
666+-- flattern the results into a single stream.
631{-# INLINE_NORMAL concatMapM #-}
668{-# INLINE_NORMAL concatMapM #-}
632concatMapM :: Monad m
669concatMapM :: Monad m
633 => (b -> m (Unfold m () c)) -> Unfold m a b -> Unfold m a c
670 => (b -> m (Unfold m () c)) -> Unfold m a b -> Unfold m a c