@@ -31,9 +31,12 @@ module Streamly.Prelude
31 -- ** General Folds
31 -- ** General Folds
36− , foldlM
35+ , foldlM'
39 -- ** Special Folds
42 -- ** Special Folds
@@ -76,6 +79,10 @@ module Streamly.Prelude
76 , fromHandle
79 , fromHandle
77 , toHandle
80 , toHandle
@@ -154,9 +161,12 @@ fromHandle h = fromStream go
154-- Elimination
161-- Elimination
155------------------------------------------------------------------------------
162------------------------------------------------------------------------------
157−-- Parallel variants of folds?
164+-- | Lazy right associative fold. For example, to fold a stream into a list:
159−-- | Right fold.
166+-- @
167+-- >> runIdentity $ foldr (:) [] (serially $ each [1,2,3])
160foldr :: (IsStream t, Monad m) => (a -> b -> b) -> b -> t m a -> m b
170foldr :: (IsStream t, Monad m) => (a -> b -> b) -> b -> t m a -> m b
161foldr step acc m = go (toStream m)
171foldr step acc m = go (toStream m)
@@ -166,7 +176,13 @@ foldr step acc m = go (toStream m)
166 yield a (Just x) = go x >>= \b -> return (step a b)
176 yield a (Just x) = go x >>= \b -> return (step a b)
167 in (runStream m1) Nothing stop yield
177 in (runStream m1) Nothing stop yield
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:
183+-- >> runIdentity $ foldrM (\\x xs -> return (x : xs)) [] (serially $ each [1,2,3])
170{-# INLINE foldrM #-}
186{-# INLINE foldrM #-}
171foldrM :: (IsStream t, Monad m) => (a -> b -> m b) -> b -> t m a -> m b
187foldrM :: (IsStream t, Monad m) => (a -> b -> m b) -> b -> t m a -> m b
172foldrM step acc m = go (toStream m)
188foldrM step acc m = go (toStream m)
@@ -177,10 +193,13 @@ foldrM step acc m = go (toStream m)
177 yield a (Just x) = (go x) >>= (step a)
193 yield a (Just x) = (go x) >>= (step a)
178 in (runStream m1) Nothing stop yield
194 in (runStream m1) Nothing stop yield
180−-- | Scan left. A strict left fold which accumulates the result of its reduction steps inside a stream, from left.
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
181−{-# INLINE scan #-}
200+{-# INLINE scanx #-}
182−scan :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
201+scanx :: 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
202+scanx step begin done m = cons (done begin) $ fromStream $ go (toStream m) begin
185 go m1 !acc = Stream $ \_ stp yld ->
204 go m1 !acc = Stream $ \_ stp yld ->
186 let stop = stp
205 let stop = stp
@@ -190,12 +209,26 @@ scan step begin done m = cons (done begin) $ fromStream $ go (toStream m) begin
190 in yld (done s) (Just (go x s))
209 in yld (done s) (Just (go x s))
191 in runStream m1 Nothing stop yield
210 in runStream m1 Nothing stop yield
193−-- | Strict left fold. This is typed to work with the foldl package. To use
212+{-# DEPRECATED scan "Please use scanx instead." #-}
194−-- it normally just pass 'id' as the third argument.
213+scan :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
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
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.
195−{-# INLINE foldl #-}
228+{-# INLINE foldx #-}
196−foldl :: (IsStream t, Monad m)
229+foldx :: (IsStream t, Monad m)
197 => (x -> a -> x) -> x -> (x -> b) -> t m a -> m b
230 => (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
200 {-# NOINLINE get #-}
233 {-# NOINLINE get #-}
@@ -216,12 +249,21 @@ foldl step begin done m = get $ go (toStream m) begin
216 Just x -> (runStream (go x s)) Nothing undefined yld
249 Just x -> (runStream (go x s)) Nothing undefined yld
217 in (runStream m1) Nothing stop yield
250 in (runStream m1) Nothing stop yield
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
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
219-- XXX replace the recursive "go" with explicit continuations.
262-- XXX replace the recursive "go" with explicit continuations.
220−-- | Strict left fold, with monadic step function. This is typed to work
263+-- | Like 'foldx', but with a monadic step function.
221−-- with the foldl package. To use directly pass 'id' as the third argument.
222−foldlM :: (IsStream t, Monad m)
264+foldxM :: (IsStream t, Monad m)
223 => (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> m b
265 => (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)
226 go !acc m1 =
268 go !acc m1 =
227 let stop = acc >>= done
269 let stop = acc >>= done
@@ -229,6 +271,15 @@ foldlM step begin done m = go begin (toStream m)
229 yield a (Just x) = acc >>= \b -> go (step b a) x
271 yield a (Just x) = acc >>= \b -> go (step b a) x
230 in (runStream m1) Nothing stop yield
272 in (runStream m1) Nothing stop yield
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
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
232-- | Decompose a stream into its head and tail. If the stream is empty, returns
283-- | Decompose a stream into its head and tail. If the stream is empty, returns
233-- 'Nothing'. If the stream is non-empty, returns 'Just (a, ma)', where 'a' is
284-- 'Nothing'. If the stream is non-empty, returns 'Just (a, ma)', where 'a' is
234-- the head of the stream and 'ma' its tail.
285-- the head of the stream and 'ma' its tail.