fold package:streaming

Strict fold of a Stream of elements that preserves the return value. The third parameter will often be id where a fold is written by hand:
>>> S.fold (+) 0 id $ each [1..10]
55 :> ()
>>> S.fold (*) 1 id $ S.fold (+) 0 id $ S.copy $ each [1..10]
3628800 :> (55 :> ())
It can be used to replace a standard Haskell type with one more suited to writing a strict accumulation function. It is also crucial to the Applicative instance for Control.Foldl.Fold We can apply such a fold purely
Control.Foldl.purely S.fold :: Monad m => Fold a b -> Stream (Of a) m r -> m (Of b r)
Thus, specializing a bit:
L.purely S.fold L.sum :: Stream (Of Int) Int r -> m (Of Int r)
mapped (L.purely S.fold L.sum) :: Stream (Stream (Of Int)) IO r -> Stream (Of Int) IO r
Here we use the Applicative instance for Control.Foldl.Fold to stream three-item segments of a stream together with their sums and products.
>>> S.print $ mapped (L.purely S.fold (liftA3 (,,) L.list L.product L.sum)) $ chunksOf 3 $ each [1..10]
([1,2,3],6,6)
([4,5,6],120,15)
([7,8,9],504,24)
([10],10,10)
Strict, monadic fold of the elements of a Stream (Of a)
Control.Foldl.impurely foldM' :: Monad m => FoldM a b -> Stream (Of a) m r -> m (b, r)
Thus to accumulate the elements of a stream as a vector, together with a random element we might write:
>>> L.impurely S.foldM (liftA2 (,) L.vectorM L.random) $ each [1..10::Int] :: IO (Of (Vector Int, Maybe Int) ())
([1,2,3,4,5,6,7,8,9,10],Just 9) :> ()
Strict, monadic fold of the elements of a Stream (Of a)
Control.Foldl.impurely foldM :: Monad m => FoldM a b -> Stream (Of a) m () -> m b
Map each element of the stream to a monoid, and take the monoidal sum of the results.
>>> S.foldMap Sum $ S.take 2 (S.stdinLn)
1<Enter>
2<Enter>
3<Enter>
Sum {getSum = 6} :> ()
Strict fold of a Stream of elements, preserving only the result of the fold, not the return value of the stream. The third parameter will often be id where a fold is written by hand:
>>> S.fold_ (+) 0 id $ each [1..10]
55
It can be used to replace a standard Haskell type with one more suited to writing a strict accumulation function. It is also crucial to the Applicative instance for Control.Foldl.Fold
Control.Foldl.purely fold :: Monad m => Fold a b -> Stream (Of a) m () -> m b
A natural right fold for consuming a stream of elements. See also the more general iterT in the Streaming module and the still more general destroy
A natural right fold for consuming a stream of elements. See also the more general iterTM in the Streaming module and the still more general destroy
foldrT (\a p -> Streaming.yield a >> p) = id
foldrT (\a p -> Pipes.yield a     >> p) :: Monad m => Stream (Of a) m r -> Producer a m r
foldrT (\a p -> Conduit.yield a   >> p) :: Monad m => Stream (Of a) m r -> Conduit a m r
streamFold reorders the arguments of destroy to be more akin to foldr It is more convenient to query in ghci to figure out what kind of 'algebra' you need to write.
>>> :t streamFold return join
(Monad m, Functor f) =>
(f (m a) -> m a) -> Stream f m a -> m a        -- iterT
>>> :t streamFold return (join . lift)
(Monad m, Monad (t m), Functor f, MonadTrans t) =>
(f (t m a) -> t m a) -> Stream f m a -> t m a  -- iterTM
>>> :t streamFold return effect
(Monad m, Functor f, Functor g) =>
(f (Stream g m r) -> Stream g m r) -> Stream f m r -> Stream g m r
>>> :t \f -> streamFold return effect (wrap . f)
(Monad m, Functor f, Functor g) =>
(f (Stream g m a) -> g (Stream g m a))
-> Stream f m a -> Stream g m a                 -- maps
>>> :t \f -> streamFold return effect (effect . fmap wrap . f)
(Monad m, Functor f, Functor g) =>
(f (Stream g m a) -> m (g (Stream g m a)))
-> Stream f m a -> Stream g m a                 -- mapped
streamFold done eff construct
= eff . iterT (return . construct . fmap eff) . fmap done
Build a Stream by unfolding steps starting from a seed. See also the specialized unfoldr in the prelude.
unfold inspect = id -- modulo the quotient we work with
unfold Pipes.next :: Monad m => Producer a m r -> Stream ((,) a) m r
unfold (curry (:>) . Pipes.next) :: Monad m => Producer a m r -> Stream (Of a) m r
Build a Stream by unfolding steps starting from a seed. In particular note that S.unfoldr S.next = id. The seed can of course be anything, but this is one natural way to consume a pipes Producer. Consider:
>>> S.stdoutLn $ S.take 2 $ S.unfoldr Pipes.next Pipes.stdinLn
hello<Enter>
hello
goodbye<Enter>
goodbye
>>> S.stdoutLn $ S.unfoldr Pipes.next (Pipes.stdinLn >-> Pipes.take 2)
hello<Enter>
hello
goodbye<Enter>
goodbye
>>> S.effects $ S.unfoldr Pipes.next (Pipes.stdinLn >-> Pipes.take 2 >-> Pipes.stdoutLn)
hello<Enter>
hello
goodbye<Enter>
goodbye
Pipes.unfoldr S.next similarly unfolds a Pipes.Producer from a stream.