@@ -103,6 +103,7 @@ module Streamly.Prelude
103103
104104 -- * Scans
105105 , scanl'
106+ , scanlM'
106107 , scanx
107108
108109 -- * Mapping
@@ -160,6 +161,22 @@ import qualified Streamly.Streams.StreamK as K
160161import qualified Streamly.Streams.StreamD as D
161162import qualified Streamly.Streams.Serial as Serial
162163
164+------------------------------------------------------------------------------
165+-- Deconstruction
166+------------------------------------------------------------------------------
167+
168+-- | Decompose a stream into its head and tail. If the stream is empty, returns
169+-- 'Nothing'. If the stream is non-empty, returns @Just (a, ma)@, where @a@ is
170+-- the head of the stream and @ma@ its tail.
171+--
172+-- @since 0.1.0
173+uncons :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (a, t m a))
174+uncons m =
175+ let stop = return Nothing
176+ single a = return (Just (a, K.nil))
177+ yieldk a r = return (Just (a, fromStream r))
178+ in (K.unStream (toStream m)) Nothing stop single yieldk
179+
163180------------------------------------------------------------------------------
164181-- Construction
165182------------------------------------------------------------------------------
@@ -379,40 +396,6 @@ foldr f = foldrM (\a b -> return (f a b))
379396foldrM :: Monad m => (a -> b -> m b) -> b -> SerialT m a -> m b
380397foldrM step acc m = D.foldrM step acc $ D.fromStreamK (toStream m)
381398
382−-- | Strict left scan with an extraction function. Like 'scanl'', but applies a
383−-- user supplied extraction function (the third argument) at each step. This is
384−-- designed to work with the @foldl@ library. The suffix @x@ is a mnemonic for
385−-- extraction.
386−--
387−-- @since 0.2.0
388−{-# INLINE scanx #-}
389−scanx :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
390−scanx step begin done m =
391− K.cons (done begin) $ fromStream $ go (toStream m) begin
392− where
393− go m1 !acc = K.Stream $ \_ stp sng yld ->
394− let single a = sng (done $ step acc a)
395− yieldk a r =
396− let s = step acc a
397− in yld (done s) (go r s)
398− in K.unStream m1 Nothing stp single yieldk
399−
400−-- |
401−-- @since 0.1.1
402−{-# DEPRECATED scan "Please use scanx instead." #-}
403−scan :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
404−scan = scanx
405−
406−-- | Strict left scan. Like 'foldl'', but returns the folded value at each
407−-- step, generating a stream of all intermediate fold results. The first
408−-- element of the stream is the user supplied initial value, and the last
409−-- element of the stream is the same as the result of 'foldl''.
410−--
411−-- @since 0.2.0
412−{-# INLINE scanl' #-}
413−scanl' :: IsStream t => (b -> a -> b) -> b -> t m a -> t m b
414−scanl' step begin m = scanx step begin id m
415−
416399-- | Strict left fold with an extraction function. Like the standard strict
417400-- left fold, but applies a user supplied extraction function (the third
418401-- argument) to the folded value at the end. This is designed to work with the
@@ -455,18 +438,6 @@ foldlM = foldxM
455438foldlM' :: Monad m => (b -> a -> m b) -> b -> SerialT m a -> m b
456439foldlM' step begin m = D.foldlM' step begin $ D.fromStreamK (toStream m)
457440
458−-- | Decompose a stream into its head and tail. If the stream is empty, returns
459−-- 'Nothing'. If the stream is non-empty, returns @Just (a, ma)@, where @a@ is
460−-- the head of the stream and @ma@ its tail.
461−--
462−-- @since 0.1.0
463−uncons :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (a, t m a))
464−uncons m =
465− let stop = return Nothing
466− single a = return (Just (a, K.nil))
467− yieldk a r = return (Just (a, fromStream r))
468− in (K.unStream (toStream m)) Nothing stop single yieldk
469−
470441-- | Write a stream of Strings to an IO Handle.
471442--
472443-- @since 0.1.0
@@ -711,6 +682,44 @@ maximum m = go Nothing (toStream m)
711682 Nothing -> Just a
712683 Just e -> Just $ max a e
713684
685+------------------------------------------------------------------------------
686+-- Scans
687+------------------------------------------------------------------------------
688+
689+-- | Strict left scan with an extraction function. Like 'scanl'', but applies a
690+-- user supplied extraction function (the third argument) at each step. This is
691+-- designed to work with the @foldl@ library. The suffix @x@ is a mnemonic for
692+-- extraction.
693+--
694+-- @since 0.2.0
695+{-# INLINE scanx #-}
696+scanx :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
697+scanx = K.scanx
698+
699+-- |
700+-- @since 0.1.1
701+{-# DEPRECATED scan "Please use scanx instead." #-}
702+scan :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
703+scan = scanx
704+
705+-- | Like 'scanl'' but with a monadic step function.
706+--
707+-- @since 0.4.0
708+{-# INLINE scanlM' #-}
709+scanlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> t m b
710+scanlM' step begin m = fromStream $ D.toStreamK $
711+ D.scanlM' step begin $ D.fromStreamK (toStream m)
712+
713+-- | Strict left scan. Like 'foldl'', but returns the folded value at each
714+-- step, generating a stream of all intermediate fold results. The first
715+-- element of the stream is the user supplied initial value, and the last
716+-- element of the stream is the same as the result of 'foldl''.
717+--
718+-- @since 0.2.0
719+{-# INLINE scanl' #-}
720+scanl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> t m b
721+scanl' step = scanlM' (\a b -> return (step a b))
722+
714723------------------------------------------------------------------------------
715724-- Transformation
716725------------------------------------------------------------------------------
@@ -743,17 +752,8 @@ mapMSerial = Serial.mapM
743752--
744753-- @since 0.3.0
745754{-# INLINE mapMaybe #-}
746−mapMaybe :: (IsStream t) => (a -> Maybe b) -> t m a -> t m b
747−mapMaybe f m = go (toStream m)
748− where
749− go m1 = fromStream $ K.Stream $ \_ stp sng yld ->
750− let single a = case f a of
751− Just b -> sng b
752− Nothing -> stp
753− yieldk a r = case f a of
754− Just b -> yld b (toStream $ go r)
755− Nothing -> (K.unStream r) Nothing stp single yieldk
756− in (K.unStream m1) Nothing stp single yieldk
755+mapMaybe :: IsStream t => (a -> Maybe b) -> t m a -> t m b
756+mapMaybe = K.mapMaybe
757757
758758-- | Like 'mapMaybe' but maps a monadic function.
759759--
@@ -788,10 +788,6 @@ mapM_ f m = D.mapM_ f $ D.fromStreamK (toStream m)
788788-- /Concurrent (do not use with 'parallely' on infinite streams)/
789789--
790790-- @since 0.1.0
791+{-# INLINE sequence #-}
791792sequence :: (IsStream t, MonadAsync m) => t m (m a) -> t m a
792−sequence m = go (toStream m)
793− where
794− go m1 = fromStream $ K.Stream $ \svr stp sng yld ->
795− let single ma = ma >>= sng
796− yieldk ma r = K.unStream (toStream $ ma |: go r) svr stp sng yld
797− in (K.unStream m1) Nothing stp single yieldk
793+sequence = K.sequence