>>> 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 rHere 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)
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) :> ()
Control.Foldl.impurely foldM :: Monad m => FoldM a b -> Stream (Of a) m () -> m b
>>> S.foldMap Sum $ S.take 2 (S.stdinLn) 1<Enter> 2<Enter> 3<Enter> Sum {getSum = 6} :> ()
>>> S.fold_ (+) 0 id $ each [1..10] 55It 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
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
>>> :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
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
>>> 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> goodbyePipes.unfoldr S.next similarly unfolds a Pipes.Producer from a stream.