@@ -41,6 +41,11 @@ module Streamly.Internal.Data.Stream.Expand
41 , interleave
41 , interleave
42 , interleaveFst
42 , interleaveFst
43 , interleaveMin
43 , interleaveMin
44+ , interleaveFstSuffix2
45 -- ** Merge
50 -- ** Merge
@@ -140,6 +145,7 @@ import Prelude hiding (concat, concatMap, zipWith)
141-- >>> import Data.Either (either)
146-- >>> import Data.Either (either)
142-- >>> import Data.IORef
147-- >>> import Data.IORef
148+-- >>> import Streamly.Internal.Data.Stream (Stream)
143-- >>> import Prelude hiding (zipWith, concatMap, concat)
149-- >>> import Prelude hiding (zipWith, concatMap, concat)
144-- >>> import qualified Streamly.Data.Array.Unboxed as Array
150-- >>> import qualified Streamly.Data.Array.Unboxed as Array
145-- >>> import qualified Streamly.Internal.Data.Fold as Fold
151-- >>> import qualified Streamly.Internal.Data.Fold as Fold
@@ -227,6 +233,74 @@ interleaveMin :: Stream m a -> Stream m a -> Stream m a
227interleaveMin s1 s2 =
233interleaveMin s1 s2 =
228 fromStreamK $ K.interleaveMin (toStreamK s1) (toStreamK s2)
234 fromStreamK $ K.interleaveMin (toStreamK s1) (toStreamK s2)
236+-- | Interleaves the outputs of two streams, yielding elements from each stream
237+-- alternately, starting from the first stream. As soon as the first stream
238+-- finishes, the output stops, discarding the remaining part of the second
239+-- stream. In this case, the last element in the resulting stream would be from
240+-- the second stream. If the second stream finishes early then the first stream
241+-- still continues to yield elements until it finishes.
243+-- >>> :set -XOverloadedStrings
244+-- >>> import Data.Functor.Identity (Identity)
245+-- >>> Stream.interleaveFstSuffix2 "abc" ",,,," :: Stream Identity Char
247+-- >>> Stream.interleaveFstSuffix2 "abc" "," :: Stream Identity Char
250+-- 'interleaveFstSuffix2' is a dual of 'interleaveFst2'.
252+-- Do not use at scale in concatMapWith.
255+{-# INLINE interleaveFstSuffix2 #-}
256+interleaveFstSuffix2 :: Monad m => Stream m b -> Stream m b -> Stream m b
257+interleaveFstSuffix2 m1 m2 =
258+ fromStreamD $ D.interleaveSuffix (toStreamD m1) (toStreamD m2)
260+-- | Interleaves the outputs of two streams, yielding elements from each stream
261+-- alternately, starting from the first stream and ending at the first stream.
262+-- If the second stream is longer than the first, elements from the second
263+-- stream are infixed with elements from the first stream. If the first stream
264+-- is longer then it continues yielding elements even after the second stream
267+-- >>> :set -XOverloadedStrings
268+-- >>> import Data.Functor.Identity (Identity)
269+-- >>> Stream.interleaveFst2 "abc" ",,,," :: Stream Identity Char
271+-- >>> Stream.interleaveFst2 "abc" "," :: Stream Identity Char
274+-- 'interleaveFst2' is a dual of 'interleaveFstSuffix2'.
276+-- Do not use at scale in concatMapWith.
279+{-# INLINE interleaveFst2 #-}
280+interleaveFst2 :: Monad m => Stream m b -> Stream m b -> Stream m b
281+interleaveFst2 m1 m2 =
282+ fromStreamD $ D.interleaveInfix (toStreamD m1) (toStreamD m2)
284+------------------------------------------------------------------------------
286+------------------------------------------------------------------------------
288+-- | Schedule the execution of two streams in a fair round-robin manner,
289+-- executing each stream once, alternately. Execution of a stream may not
290+-- necessarily result in an output, a stream may chose to @Skip@ producing an
291+-- element until later giving the other stream a chance to run. Therefore, this
292+-- combinator fairly interleaves the execution of two streams rather than
293+-- fairly interleaving the output of the two streams. This can be useful in
294+-- co-operative multitasking without using explicit threads. This can be used
295+-- as an alternative to `async`.
297+-- Do not use at scale in concatMapWith.
300+{-# INLINE roundrobin #-}
301+roundrobin :: Monad m => Stream m b -> Stream m b -> Stream m b
302+roundrobin m1 m2 = fromStreamD $ D.roundRobin (toStreamD m1) (toStreamD m2)
230------------------------------------------------------------------------------
304------------------------------------------------------------------------------
231-- Merging (sorted streams)
305-- Merging (sorted streams)
232------------------------------------------------------------------------------
306------------------------------------------------------------------------------
@@ -361,7 +435,7 @@ unfoldInterleave u m =
361{-# INLINE unfoldRoundRobin #-}
435{-# INLINE unfoldRoundRobin #-}
362unfoldRoundRobin ::Monad m => Unfold m a b -> Stream m a -> Stream m b
436unfoldRoundRobin ::Monad m => Unfold m a b -> Stream m a -> Stream m b
363unfoldRoundRobin u m =
437unfoldRoundRobin u m =
364− fromStreamD $ D.unfoldManyInterleave u (toStreamD m)
438+ fromStreamD $ D.unfoldManyRoundRobin u (toStreamD m)
366------------------------------------------------------------------------------
440------------------------------------------------------------------------------
367-- Combine N Streams - interpose
441-- Combine N Streams - interpose
@@ -407,7 +481,7 @@ interposeSuffix x unf str =
407-- > unfoldMany unf str =
481-- > unfoldMany unf str =
408-- > gintercalate unf str (UF.nilM (\_ -> return ())) (repeat ())
482-- > gintercalate unf str (UF.nilM (\_ -> return ())) (repeat ())
410−-- | 'interleaveInfix' followed by unfold and concat.
484+-- | 'interleaveFst' followed by unfold and concat.
412-- /Pre-release/
486-- /Pre-release/
413{-# INLINE gintercalate #-}
487{-# INLINE gintercalate #-}
@@ -438,7 +512,7 @@ intercalate :: Monad m
438intercalate unf seed str = fromStreamD $
512intercalate unf seed str = fromStreamD $
439 D.unfoldMany unf $ D.intersperse seed (toStreamD str)
513 D.unfoldMany unf $ D.intersperse seed (toStreamD str)
441−-- | 'interleaveSuffix' followed by unfold and concat.
515+-- | 'interleaveFstSuffix2' followed by unfold and concat.
443-- /Pre-release/
517-- /Pre-release/
444{-# INLINE gintercalateSuffix #-}
518{-# INLINE gintercalateSuffix #-}