@@ -31,9 +31,12 @@ module Streamly.Prelude
3131 -- ** General Folds
3232 , foldr
3333 , foldrM
34− , scan
35− , foldl
36− , foldlM
34+ , foldl'
35+ , foldlM'
36+ , scanl'
37+ , scanx
38+ , foldx
39+ , foldxM
3740 , uncons
3841
3942 -- ** Special Folds
@@ -76,6 +79,10 @@ module Streamly.Prelude
7679 , fromHandle
7780 , toHandle
7881
82+ -- * Deprecated
83+ , scan
84+ , foldl
85+ , foldlM
7986 )
8087where
8188
@@ -154,9 +161,12 @@ fromHandle h = fromStream go
154161-- Elimination
155162------------------------------------------------------------------------------
156163
157−-- Parallel variants of folds?
158−
159−-- | Right fold.
164+-- | Lazy right associative fold. For example, to fold a stream into a list:
165+--
166+-- @
167+-- >> runIdentity $ foldr (:) [] (serially $ each [1,2,3])
168+-- [1,2,3]
169+-- @
160170foldr :: (IsStream t, Monad m) => (a -> b -> b) -> b -> t m a -> m b
161171foldr step acc m = go (toStream m)
162172 where
@@ -166,7 +176,13 @@ foldr step acc m = go (toStream m)
166176 yield a (Just x) = go x >>= \b -> return (step a b)
167177 in (runStream m1) Nothing stop yield
168178
169−-- | Right fold with a monadic step function. See 'toList' for an example use.
179+-- | Lazy right fold with a monadic step function. For example, to fold a
180+-- stream into a list:
181+--
182+-- @
183+-- >> runIdentity $ foldrM (\\x xs -> return (x : xs)) [] (serially $ each [1,2,3])
184+-- [1,2,3]
185+-- @
170186{-# INLINE foldrM #-}
171187foldrM :: (IsStream t, Monad m) => (a -> b -> m b) -> b -> t m a -> m b
172188foldrM step acc m = go (toStream m)
@@ -177,10 +193,13 @@ foldrM step acc m = go (toStream m)
177193 yield a (Just x) = (go x) >>= (step a)
178194 in (runStream m1) Nothing stop yield
179195
180−-- | Scan left. A strict left fold which accumulates the result of its reduction steps inside a stream, from left.
181−{-# INLINE scan #-}
182−scan :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
183−scan step begin done m = cons (done begin) $ fromStream $ go (toStream m) begin
196+-- | Strict left scan with an extraction function. Like 'scanl'', but applies a
197+-- user supplied extraction function (the third argument) at each step. This is
198+-- designed to work with the @foldl@ library. The suffix @x@ is a mnemonic for
199+-- extraction.
200+{-# INLINE scanx #-}
201+scanx :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
202+scanx step begin done m = cons (done begin) $ fromStream $ go (toStream m) begin
184203 where
185204 go m1 !acc = Stream $ \_ stp yld ->
186205 let stop = stp
@@ -190,12 +209,26 @@ scan step begin done m = cons (done begin) $ fromStream $ go (toStream m) begin
190209 in yld (done s) (Just (go x s))
191210 in runStream m1 Nothing stop yield
192211
193−-- | Strict left fold. This is typed to work with the foldl package. To use
194−-- it normally just pass 'id' as the third argument.
195−{-# INLINE foldl #-}
196−foldl :: (IsStream t, Monad m)
212+{-# DEPRECATED scan "Please use scanx instead." #-}
213+scan :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
214+scan = scanx
215+
216+-- | Strict left scan. Like 'foldl'', but returns the folded value at each
217+-- step, generating a stream of all intermediate fold results. The first
218+-- element of the stream is the user supplied initial value, and the last
219+-- element of the stream is the same as the result of 'foldl''.
220+{-# INLINE scanl' #-}
221+scanl' :: IsStream t => (b -> a -> b) -> b -> t m a -> t m b
222+scanl' step begin m = scanx step begin id m
223+
224+-- | Strict left fold with an extraction function. Like the standard strict
225+-- left fold, but applies a user supplied extraction function (the third
226+-- argument) to the folded value at the end. This is designed to work with the
227+-- @foldl@ library. The suffix @x@ is a mnemonic for extraction.
228+{-# INLINE foldx #-}
229+foldx :: (IsStream t, Monad m)
197230 => (x -> a -> x) -> x -> (x -> b) -> t m a -> m b
198−foldl step begin done m = get $ go (toStream m) begin
231+foldx step begin done m = get $ go (toStream m) begin
199232 where
200233 {-# NOINLINE get #-}
201234 get m1 =
@@ -216,12 +249,21 @@ foldl step begin done m = get $ go (toStream m) begin
216249 Just x -> (runStream (go x s)) Nothing undefined yld
217250 in (runStream m1) Nothing stop yield
218251
252+{-# DEPRECATED foldl "Please use foldx instead." #-}
253+foldl :: (IsStream t, Monad m)
254+ => (x -> a -> x) -> x -> (x -> b) -> t m a -> m b
255+foldl = foldx
256+
257+-- | Strict left associative fold.
258+{-# INLINE foldl' #-}
259+foldl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> m b
260+foldl' step begin m = foldx step begin id m
261+
219262-- XXX replace the recursive "go" with explicit continuations.
220−-- | Strict left fold, with monadic step function. This is typed to work
221−-- with the foldl package. To use directly pass 'id' as the third argument.
222−foldlM :: (IsStream t, Monad m)
263+-- | Like 'foldx', but with a monadic step function.
264+foldxM :: (IsStream t, Monad m)
223265 => (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> m b
224−foldlM step begin done m = go begin (toStream m)
266+foldxM step begin done m = go begin (toStream m)
225267 where
226268 go !acc m1 =
227269 let stop = acc >>= done
@@ -229,6 +271,15 @@ foldlM step begin done m = go begin (toStream m)
229271 yield a (Just x) = acc >>= \b -> go (step b a) x
230272 in (runStream m1) Nothing stop yield
231273
274+{-# DEPRECATED foldlM "Please use foldxM instead." #-}
275+foldlM :: (IsStream t, Monad m)
276+ => (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> m b
277+foldlM = foldxM
278+
279+-- | Like 'foldl'' but with a monadic step function.
280+foldlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> m b
281+foldlM' step begin m = foldxM step (return begin) return m
282+
232283-- | Decompose a stream into its head and tail. If the stream is empty, returns
233284-- 'Nothing'. If the stream is non-empty, returns 'Just (a, ma)', where 'a' is
234285-- the head of the stream and 'ma' its tail.