iterateM package:streamly

>>> iterateM f m = m >>= \a -> return a `Stream.consM` iterateM f (f a)
Generate an infinite stream with the first element generated by the action m and each successive element derived by applying the monadic function f on the previous element.
>>> pr n = threadDelay 1000000 >> print n

>>> :{
Stream.iterateM (\x -> pr x >> return (x + 1)) (return 0)
& Stream.take 3
& Stream.fromSerial
& Stream.toList
:}
0
1
[0,1,2]
When run concurrently, the next iteration can run concurrently with the processing of the previous iteration. Note that more than one iteration cannot run concurrently as the next iteration depends on the output of the previous iteration.
>>> :{
Stream.iterateM (\x -> pr x >> return (x + 1)) (return 0)
& Stream.delay 1
& Stream.take 3
& Stream.fromAsync
& Stream.toList
:}
0
1
...
Concurrent Since: 0.1.2 Since: 0.7.0 (signature change)
In an Either stream iterate on Lefts. This is a special case of iterateMapWith:
iterateMapLeftsWith combine f = iterateMapWith combine (either f (const nil))
To traverse a directory tree:
iterateMapLeftsWith serial Dir.toEither (fromPure (Left "tmp"))
Pre-release
Like iterateM but iterates after mapping a stream generator on the output. Yield an input element in the output stream, map a stream generator on it and then do the same on the resulting stream. This can be used for a depth first traversal of a tree like structure. Note that iterateM is a special case of iterateMapWith:
iterateM f = iterateMapWith serial (fromEffect . f) . fromEffect
It can be used to traverse a tree structure. For example, to list a directory tree:
Stream.iterateMapWith Stream.serial
(either Dir.toEither (const nil))
(fromPure (Left "tmp"))
Pre-release
Iterate a fold generator on a stream. The initial value b is used to generate the first fold, the fold is applied on the stream and the result of the fold is used to generate the next fold and so on.
>>> import Data.Monoid (Sum(..))
>>> f x = return (Fold.take 2 (Fold.sconcat x))
>>> s = Stream.map Sum $ Stream.fromList [1..10]
>>> Stream.toList $ Stream.map getSum $ Stream.foldIterateM f (pure 0) s
[3,10,21,36,55,55]
This is the streaming equivalent of monad like sequenced application of folds where next fold is dependent on the previous fold. Pre-release
Like foldIterateM but using the Refold type instead. This could be much more efficient due to stream fusion. Internal