@@ -32,6 +32,8 @@ module Streamly.Streams.Serial
3232 , InterleavedT -- deprecated
3333 , WSerial
3434 , wSerial
35+ , wSerialEndByFirst
36+ , wSerialEndByAny
3537 , (<=>) -- deprecated
3638 , wSerially
3739 , interleaving -- deprecated
@@ -295,6 +297,8 @@ instance IsStream WSerialT where
295297
296298-- | Polymorphic version of the 'Semigroup' operation '<>' of 'WSerialT'.
297299-- Interleaves two streams, yielding one element from each stream alternately.
300+-- When one stream stops the rest of the other stream is used in the output
301+-- stream.
298302--
299303-- @since 0.2.0
300304{-# INLINE wSerial #-}
@@ -305,6 +309,35 @@ wSerial m1 m2 = mkStream $ \st yld sng stp -> do
305309 yieldk a r = yld a (wSerial m2 r)
306310 foldStream st yieldk single stop m1
307311
312+-- | Like `wSerial` but stops interleaving as soon as the first stream stops.
313+--
314+-- @since 0.7.0
315+{-# INLINE wSerialEndByFirst #-}
316+wSerialEndByFirst :: IsStream t => t m a -> t m a -> t m a
317+wSerialEndByFirst m1 m2 = mkStream $ \st yld sng stp -> do
318+ let yieldFirst a r = yld a (yieldSecond r m2)
319+ in foldStream st yieldFirst sng stp m1
320+
321+ where
322+
323+ yieldSecond s1 s2 = mkStream $ \st yld sng stp -> do
324+ let stop = foldStream st yld sng stp s1
325+ single a = yld a s1
326+ yieldk a r = yld a (wSerial s1 r)
327+ in foldStream st yieldk single stop s2
328+
329+-- | Like `wSerial` but stops interleaving as soon as any of the two streams
330+-- stops.
331+--
332+-- @since 0.7.0
333+{-# INLINE wSerialEndByAny #-}
334+wSerialEndByAny :: IsStream t => t m a -> t m a -> t m a
335+wSerialEndByAny m1 m2 = mkStream $ \st yld sng stp -> do
336+ let stop = stp
337+ single a = sng a
338+ yieldk a r = yld a (wSerial m2 r)
339+ foldStream st yieldk single stop m1
340+
308341instance Semigroup (WSerialT m a) where
309342 (<>) = wSerial
310343