{-#LANGUAGE RankNTypes #-} module Streaming ( -- * Free monad transformer -- $stream Stream, -- * Constructing a 'Stream' on a base functor unfold, construct, for, layer, layers, replicates, repeats, repeatsM, delay, wrap, -- * Transforming streams decompose, maps, mapsM, distribute, eithers, -- * Inspecting a stream inspect, -- * Zipping streams zips, zipsWith, interleaves, -- * Eliminating a 'Stream' iterTM, iterT, destroy, mapsM_, run, -- * Splitting and joining 'Stream's splitsAt, takes, chunksOf, concats, intercalates, -- * Base functor for streams of individual items Of (..), lazily, strictly, -- * re-exports MFunctor(..), MMonad(..), MonadTrans(..), MonadIO(..), Compose(..), join, liftA2, liftA3, void, ) where import Streaming.Internal import Streaming.Prelude import Control.Monad.Morph import Control.Monad import Control.Applicative import Control.Monad.Trans import Data.Functor.Compose {- $stream The 'Stream' data type is equivalent to @FreeT@ and can represent any effectful succession of steps, where the form of the steps or 'commands' is specified by the first (functor) parameter. The present module exports functions that pertain to that general case. So for example, if the functor is > data Split r = Split r r The @Stream Split m r@ will the type of binary trees with @r@ at the leaves and in which each episode of branching results from an @m@-effect. In the simplest case, the base functor is @ (,) a @. Here the news or /command/ at each step is an /individual element of type/ @ a @, i.e. the command is a @yield@ statement. The associated @Streaming@ 'Streaming.Prelude' uses the left-strict pair @Of a b@ in place of the Haskell pair @(a,b)@ and operations like e.g. > chunksOf :: Monad m => Int -> Stream f m r -> Stream (Stream f m) m r > mapsM Streaming.Prelude.length' :: Stream (Stream (Of a) m) r -> Stream (Of Int) m r -} {-| Map a stream to its church encoding; compare @Data.List.foldr@ This is the @safe_destroy@ exported by the @Internal@ module. Typical @FreeT@ operators can be defined in terms of @destroy@ e.g. > iterT :: (Functor f, Monad m) => (f (m a) -> m a) -> Stream f m a -> m a > iterT out stream = destroy stream out join return > iterTM :: (Functor f, Monad m, MonadTrans t, Monad (t m)) => (f (t m a) -> t m a) -> Stream f m a -> t m a > iterTM out stream = destroy stream out (join . lift) return > concats :: (Monad m, MonadTrans t, Monad (t m)) => Stream (t m) m a -> t m a > concats stream = destroy stream join (join . lift) return -}