-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Compositional pipelines
--   
--   pipes is a clean and powerful stream processing library that
--   lets you build and connect reusable streaming components
--   
--   Advantages over traditional streaming libraries:
--   
--   
--   
- Concise API: Use simple commands like for,
--   (>->), await, and yield
--   
- Blazing fast: Implementation tuned for speed, including
--   shortcut fusion
--   
- Lightweight Dependency: pipes is small and
--   compiles very rapidly, including dependencies
--   
- Elegant semantics: Use practical category theory
--   
- ListT: Correct implementation of ListT that
--   interconverts with pipes
--   
- Bidirectionality: Implement duplex channels
--   
- Extensive Documentation: Second to none!
--   
--   
--   Import Pipes to use the library.
--   
--   Read Pipes.Tutorial for an extensive tutorial.
@package pipes
@version 4.3.16

-- | This is an internal module, meaning that it is unsafe to import unless
--   you understand the risks.
--   
--   This module provides a fast implementation by weakening the monad
--   transformer laws. These laws do not hold if you can pattern match on
--   the constructors, as the following counter-example illustrates:
--   
--   
--   lift . return = M . return . Pure
--   
--   return = Pure
--   
--   lift . return /= return
--   
--   
--   You do not need to worry about this if you do not import this module,
--   since the other modules in this library do not export the constructors
--   or export any functions which can violate the monad transformer laws.
module Pipes.Internal

-- | A Proxy is a monad transformer that receives and sends
--   information on both an upstream and downstream interface.
--   
--   The type variables signify:
--   
--   
--   
- a' and a - The upstream interface, where
--   (a')s go out and (a)s come in
--   
- b' and b - The downstream interface, where
--   (b)s go out and (b')s come in
--   
- m  - The base monad
--   
- r  - The return value
--   
data Proxy a' a b' b m r
Request :: a' -> (a -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
Respond :: b -> (b' -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
M :: m (Proxy a' a b' b m r) -> Proxy a' a b' b m r
Pure :: r -> Proxy a' a b' b m r

-- | unsafeHoist is like hoist, but faster.
--   
--   This is labeled as unsafe because you will break the monad transformer
--   laws if you do not pass a monad morphism as the first argument. This
--   function is safe if you pass a monad morphism as the first argument.
unsafeHoist :: Functor m => (forall x. m x -> n x) -> Proxy a' a b' b m r -> Proxy a' a b' b n r

-- | The monad transformer laws are correct when viewed through the
--   observe function:
--   
--   
--   observe (lift (return r)) = observe (return r)
--   
--   observe (lift (m >>= f)) = observe (lift m >>= lift . f)
--   
--   
--   This correctness comes at a small cost to performance, so use this
--   function sparingly.
--   
--   This function is a convenience for low-level pipes
--   implementers. You do not need to use observe if you stick to
--   the safe API.
observe :: Monad m => Proxy a' a b' b m r -> Proxy a' a b' b m r

-- | The empty type, used to close output ends
type X = Void

-- | Use closed to "handle" impossible outputs
closed :: X -> a
instance GHC.Base.Functor m => GHC.Base.Functor (Pipes.Internal.Proxy a' a b' b m)
instance GHC.Base.Functor m => GHC.Base.Applicative (Pipes.Internal.Proxy a' a b' b m)
instance GHC.Base.Functor m => GHC.Base.Monad (Pipes.Internal.Proxy a' a b' b m)
instance (GHC.Base.Functor m, GHC.Base.Semigroup r) => GHC.Base.Semigroup (Pipes.Internal.Proxy a' a b' b m r)
instance (GHC.Base.Functor m, GHC.Base.Monoid r, GHC.Base.Semigroup r) => GHC.Base.Monoid (Pipes.Internal.Proxy a' a b' b m r)
instance Control.Monad.Trans.Class.MonadTrans (Pipes.Internal.Proxy a' a b' b)
instance Control.Monad.Morph.MFunctor (Pipes.Internal.Proxy a' a b' b)
instance Control.Monad.Morph.MMonad (Pipes.Internal.Proxy a' a b' b)
instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Pipes.Internal.Proxy a' a b' b m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Pipes.Internal.Proxy a' a b' b m)
instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Pipes.Internal.Proxy a' a b' b m)
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Pipes.Internal.Proxy a' a b' b m)
instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Pipes.Internal.Proxy a' a b' b m)
instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Pipes.Internal.Proxy a' a b' b m)
instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Pipes.Internal.Proxy a' a b' b m)
instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Pipes.Internal.Proxy a' a b' b m)

-- | The core functionality for the Proxy monad transformer
--   
--   Read Pipes.Tutorial if you want a beginners tutorial explaining
--   how to use this library. The documentation in this module targets more
--   advanced users who want to understand the theory behind this library.
--   
--   This module is not exported by default, and I recommend you use the
--   unidirectional operations exported by the Pipes module if you
--   can. You should only use this module if you require advanced features
--   like:
--   
--   
--   
- bidirectional communication, or:
--   
- push-based Pipes.
--   
module Pipes.Core

-- | A Proxy is a monad transformer that receives and sends
--   information on both an upstream and downstream interface.
--   
--   The type variables signify:
--   
--   
--   
- a' and a - The upstream interface, where
--   (a')s go out and (a)s come in
--   
- b' and b - The downstream interface, where
--   (b)s go out and (b')s come in
--   
- m  - The base monad
--   
- r  - The return value
--   
data Proxy a' a b' b m r

-- | Run a self-contained Effect, converting it back to the base
--   monad
runEffect :: Monad m => Effect m r -> m r

-- | Send a value of type a downstream and block waiting for a
--   reply of type a'
--   
--   respond is the identity of the respond category.
respond :: Functor m => a -> Proxy x' x a' a m a'

-- | Compose two unfolds, creating a new unfold
--   
--   
--   (f />/ g) x = f x //> g
--   
--   
--   (/>/) is the composition operator of the respond category.
(/>/) :: Functor m => (a -> Proxy x' x b' b m a') -> (b -> Proxy x' x c' c m b') -> a -> Proxy x' x c' c m a'
infixr 4 />/

-- | (p //> f) replaces each respond in p with
--   f.
--   
--   Point-ful version of (/>/)
(//>) :: Functor m => Proxy x' x b' b m a' -> (b -> Proxy x' x c' c m b') -> Proxy x' x c' c m a'
infixl 3 //>

-- | Send a value of type a' upstream and block waiting for a
--   reply of type a
--   
--   request is the identity of the request category.
request :: Functor m => a' -> Proxy a' a y' y m a

-- | Compose two folds, creating a new fold
--   
--   
--   (f \>\ g) x = f >\\ g x
--   
--   
--   (\>\) is the composition operator of the request category.
(\>\) :: Functor m => (b' -> Proxy a' a y' y m b) -> (c' -> Proxy b' b y' y m c) -> c' -> Proxy a' a y' y m c
infixl 5 \>\

-- | (f >\\ p) replaces each request in p with
--   f.
--   
--   Point-ful version of (\>\)
(>\\) :: Functor m => (b' -> Proxy a' a y' y m b) -> Proxy b' b y' y m c -> Proxy a' a y' y m c
infixr 4 >\\

-- | Forward responses followed by requests
--   
--   
--   push = respond >=> request >=> push
--   
--   
--   push is the identity of the push category.
push :: Functor m => a -> Proxy a' a a' a m r

-- | Compose two proxies blocked while requesting data, creating a
--   new proxy blocked while requesting data
--   
--   
--   (f >~> g) x = f x >>~ g
--   
--   
--   (>~>) is the composition operator of the push category.
(>~>) :: Functor m => (_a -> Proxy a' a b' b m r) -> (b -> Proxy b' b c' c m r) -> _a -> Proxy a' a c' c m r
infixr 8 >~>

-- | (p >>~ f) pairs each respond in p with
--   a request in f.
--   
--   Point-ful version of (>~>)
(>>~) :: Functor m => Proxy a' a b' b m r -> (b -> Proxy b' b c' c m r) -> Proxy a' a c' c m r
infixl 7 >>~

-- | Forward requests followed by responses:
--   
--   
--   pull = request >=> respond >=> pull
--   
--   
--   pull is the identity of the pull category.
pull :: Functor m => a' -> Proxy a' a a' a m r

-- | Compose two proxies blocked in the middle of responding,
--   creating a new proxy blocked in the middle of responding
--   
--   
--   (f >+> g) x = f +>> g x
--   
--   
--   (>+>) is the composition operator of the pull category.
(>+>) :: Functor m => (b' -> Proxy a' a b' b m r) -> (_c' -> Proxy b' b c' c m r) -> _c' -> Proxy a' a c' c m r
infixl 7 >+>

-- | (f +>> p) pairs each request in p with
--   a respond in f.
--   
--   Point-ful version of (>+>)
(+>>) :: Functor m => (b' -> Proxy a' a b' b m r) -> Proxy b' b c' c m r -> Proxy a' a c' c m r
infixr 6 +>>

-- | Switch the upstream and downstream ends
reflect :: Functor m => Proxy a' a b' b m r -> Proxy b b' a a' m r

-- | The empty type, used to close output ends
type X = Void

-- | An effect in the base monad
--   
--   Effects neither await nor yield
type Effect = Proxy X () () X

-- | Producers can only yield
type Producer b = Proxy X () () b

-- | Pipes can both await and yield
type Pipe a b = Proxy () a () b

-- | Consumers can only await
type Consumer a = Proxy () a () X

-- | Client a' a sends requests of type a' and receives
--   responses of type a.
--   
--   Clients only request and never respond.
type Client a' a = Proxy a' a () X

-- | Server b' b receives requests of type b' and sends
--   responses of type b.
--   
--   Servers only respond and never request.
type Server b' b = Proxy X () b' b

-- | Like Effect, but with a polymorphic type
type Effect' m r = forall x' x y' y. Proxy x' x y' y m r

-- | Like Producer, but with a polymorphic type
type Producer' b m r = forall x' x. Proxy x' x () b m r

-- | Like Consumer, but with a polymorphic type
type Consumer' a m r = forall y' y. Proxy () a y' y m r

-- | Like Client, but with a polymorphic type
type Client' a' a m r = forall y' y. Proxy a' a y' y m r

-- | Like Server, but with a polymorphic type
type Server' b' b m r = forall x' x. Proxy x' x b' b m r

-- | Equivalent to (/>/) with the arguments flipped
(\<\) :: Functor m => (b -> Proxy x' x c' c m b') -> (a -> Proxy x' x b' b m a') -> a -> Proxy x' x c' c m a'
infixl 4 \<\

-- | Equivalent to (\>\) with the arguments flipped
(/</) :: Functor m => (c' -> Proxy b' b x' x m c) -> (b' -> Proxy a' a x' x m b) -> c' -> Proxy a' a x' x m c
infixr 5 /</

-- | Equivalent to (>~>) with the arguments flipped
(<~<) :: Functor m => (b -> Proxy b' b c' c m r) -> (a -> Proxy a' a b' b m r) -> a -> Proxy a' a c' c m r
infixl 8 <~<

-- | Equivalent to (>>~) with the arguments flipped
(~<<) :: Functor m => (b -> Proxy b' b c' c m r) -> Proxy a' a b' b m r -> Proxy a' a c' c m r
infixr 7 ~<<

-- | Equivalent to (>+>) with the arguments flipped
(<+<) :: Functor m => (c' -> Proxy b' b c' c m r) -> (b' -> Proxy a' a b' b m r) -> c' -> Proxy a' a c' c m r
infixr 7 <+<

-- | Equivalent to (//>) with the arguments flipped
(<\\) :: Functor m => (b -> Proxy x' x c' c m b') -> Proxy x' x b' b m a' -> Proxy x' x c' c m a'
infixr 3 <\\

-- | Equivalent to (>\\) with the arguments flipped
(//<) :: Functor m => Proxy b' b y' y m c -> (b' -> Proxy a' a y' y m b) -> Proxy a' a y' y m c
infixl 4 //<

-- | Equivalent to (+>>) with the arguments flipped
(<<+) :: Functor m => Proxy b' b c' c m r -> (b' -> Proxy a' a b' b m r) -> Proxy a' a c' c m r
infixl 6 <<+

-- | Use closed to "handle" impossible outputs
closed :: X -> a

-- | This module is the recommended entry point to the pipes
--   library.
--   
--   Read Pipes.Tutorial if you want a tutorial explaining how to
--   use this library.
module Pipes

-- | A Proxy is a monad transformer that receives and sends
--   information on both an upstream and downstream interface.
--   
--   The type variables signify:
--   
--   
--   
- a' and a - The upstream interface, where
--   (a')s go out and (a)s come in
--   
- b' and b - The downstream interface, where
--   (b)s go out and (b')s come in
--   
- m  - The base monad
--   
- r  - The return value
--   
data Proxy a' a b' b m r

-- | The empty type, used to close output ends
type X = Void

-- | An effect in the base monad
--   
--   Effects neither await nor yield
type Effect = Proxy X () () X

-- | Like Effect, but with a polymorphic type
type Effect' m r = forall x' x y' y. Proxy x' x y' y m r

-- | Run a self-contained Effect, converting it back to the base
--   monad
runEffect :: Monad m => Effect m r -> m r

-- | Producers can only yield
type Producer b = Proxy X () () b

-- | Like Producer, but with a polymorphic type
type Producer' b m r = forall x' x. Proxy x' x () b m r

-- | Produce a value
--   
--   
--   yield :: Monad m => a -> Producer a m ()
--   yield :: Monad m => a -> Pipe   x a m ()
--   
yield :: Functor m => a -> Proxy x' x () a m ()

-- | (for p body) loops over p replacing each
--   yield with body.
--   
--   
--   for :: Functor m => Producer b m r -> (b -> Effect       m ()) -> Effect       m r
--   for :: Functor m => Producer b m r -> (b -> Producer   c m ()) -> Producer   c m r
--   for :: Functor m => Pipe   x b m r -> (b -> Consumer x   m ()) -> Consumer x   m r
--   for :: Functor m => Pipe   x b m r -> (b -> Pipe     x c m ()) -> Pipe     x c m r
--   
--   
--   The following diagrams show the flow of information:
--   
--   
--                                 .--->   b
--                                /        |
--      +-----------+            /   +-----|-----+                 +---------------+
--      |           |           /    |     v     |                 |               |
--      |           |          /     |           |                 |               |
--   x ==>    p    ==> b   ---'   x ==>   body  ==> c     =     x ==> for p body  ==> c
--      |           |                |           |                 |               |
--      |     |     |                |     |     |                 |       |       |
--      +-----|-----+                +-----|-----+                 +-------|-------+
--            v                            v                               v
--            r                            ()                              r
--   
--   
--   For a more complete diagram including bidirectional flow, see
--   Pipes.Core#respond-diagram.
for :: Functor m => Proxy x' x b' b m a' -> (b -> Proxy x' x c' c m b') -> Proxy x' x c' c m a'

-- | Compose loop bodies
--   
--   
--   (~>) :: Functor m => (a -> Producer b m r) -> (b -> Effect       m ()) -> (a -> Effect       m r)
--   (~>) :: Functor m => (a -> Producer b m r) -> (b -> Producer   c m ()) -> (a -> Producer   c m r)
--   (~>) :: Functor m => (a -> Pipe   x b m r) -> (b -> Consumer x   m ()) -> (a -> Consumer x   m r)
--   (~>) :: Functor m => (a -> Pipe   x b m r) -> (b -> Pipe     x c m ()) -> (a -> Pipe     x c m r)
--   
--   
--   The following diagrams show the flow of information:
--   
--   
--            a                    .--->   b                              a
--            |                   /        |                              |
--      +-----|-----+            /   +-----|-----+                 +------|------+
--      |     v     |           /    |     v     |                 |      v      |
--      |           |          /     |           |                 |             |
--   x ==>    f    ==> b   ---'   x ==>    g    ==> c     =     x ==>   f ~> g  ==> c
--      |           |                |           |                 |             |
--      |     |     |                |     |     |                 |      |      |
--      +-----|-----+                +-----|-----+                 +------|------+
--            v                            v                              v
--            r                            ()                             r
--   
--   
--   For a more complete diagram including bidirectional flow, see
--   Pipes.Core#respond-diagram.
(~>) :: Functor m => (a -> Proxy x' x b' b m a') -> (b -> Proxy x' x c' c m b') -> a -> Proxy x' x c' c m a'
infixr 4 ~>

-- | (~>) with the arguments flipped
(<~) :: Functor m => (b -> Proxy x' x c' c m b') -> (a -> Proxy x' x b' b m a') -> a -> Proxy x' x c' c m a'
infixl 4 <~

-- | Consumers can only await
type Consumer a = Proxy () a () X

-- | Like Consumer, but with a polymorphic type
type Consumer' a m r = forall y' y. Proxy () a y' y m r

-- | Consume a value
--   
--   
--   await :: Functor m => Pipe a y m a
--   
await :: Functor m => Consumer' a m a

-- | (draw >~ p) loops over p replacing each
--   await with draw
--   
--   
--   (>~) :: Functor m => Effect       m b -> Consumer b   m c -> Effect       m c
--   (>~) :: Functor m => Consumer a   m b -> Consumer b   m c -> Consumer a   m c
--   (>~) :: Functor m => Producer   y m b -> Pipe     b y m c -> Producer   y m c
--   (>~) :: Functor m => Pipe     a y m b -> Pipe     b y m c -> Pipe     a y m c
--   
--   
--   The following diagrams show the flow of information:
--   
--   
--      +-----------+                 +-----------+                 +-------------+
--      |           |                 |           |                 |             |
--      |           |                 |           |                 |             |
--   a ==>    f    ==> y   .--->   b ==>    g    ==> y     =     a ==>   f >~ g  ==> y
--      |           |     /           |           |                 |             |
--      |     |     |    /            |     |     |                 |      |      |
--      +-----|-----+   /             +-----|-----+                 +------|------+
--            v        /                    v                              v
--            b   ----'                     c                              c
--   
--   
--   For a more complete diagram including bidirectional flow, see
--   Pipes.Core#request-diagram.
(>~) :: Functor m => Proxy a' a y' y m b -> Proxy () b y' y m c -> Proxy a' a y' y m c
infixr 5 >~

-- | (>~) with the arguments flipped
(~<) :: Functor m => Proxy () b y' y m c -> Proxy a' a y' y m b -> Proxy a' a y' y m c
infixl 5 ~<

-- | Pipes can both await and yield
type Pipe a b = Proxy () a () b

-- | The identity Pipe, analogous to the Unix cat program
cat :: Functor m => Pipe a a m r

-- | Pipe composition, analogous to the Unix pipe operator
--   
--   
--   (>->) :: Functor m => Producer b m r -> Consumer b   m r -> Effect       m r
--   (>->) :: Functor m => Producer b m r -> Pipe     b c m r -> Producer   c m r
--   (>->) :: Functor m => Pipe   a b m r -> Consumer b   m r -> Consumer a   m r
--   (>->) :: Functor m => Pipe   a b m r -> Pipe     b c m r -> Pipe     a c m r
--   
--   
--   The following diagrams show the flow of information:
--   
--   
--      +-----------+     +-----------+                 +-------------+
--      |           |     |           |                 |             |
--      |           |     |           |                 |             |
--   a ==>    f    ==> b ==>    g    ==> c     =     a ==>  f >-> g  ==> c
--      |           |     |           |                 |             |
--      |     |     |     |     |     |                 |      |      |
--      +-----|-----+     +-----|-----+                 +------|------+
--            v                 v                              v
--            r                 r                              r
--   
--   
--   For a more complete diagram including bidirectional flow, see
--   Pipes.Core#pull-diagram.
(>->) :: Functor m => Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
infixl 7 >->

-- | (>->) with the arguments flipped
(<-<) :: Functor m => Proxy () b c' c m r -> Proxy a' a () b m r -> Proxy a' a c' c m r
infixr 7 <-<

-- | The list monad transformer, which extends a monad with non-determinism
--   
--   The type variables signify:
--   
--   
--   
- m - The base monad
--   
- a - The values that the computation yields
--   throughout its execution
--   
--   
--   For basic construction and composition of ListT computations,
--   much can be accomplished using common typeclass methods.
--   
--   
--   
- return corresponds to yield, yielding a single
--   value.
--   
- (>>=) corresponds to for, calling the second
--   computation once for each time the first computation
--   yields.
--   
- mempty neither yields any values nor produces any
--   effects in the base monad.
--   
- (<>) sequences two computations, yielding all
--   the values of the first followed by all the values of the second.
--   
- lift converts an action in the base monad into a ListT
--   computation which performs the action and yields a single
--   value.
--   
--   
--   ListT is a newtype wrapper for Producer. You will likely
--   need to use Select and enumerate to convert back and
--   forth between these two types to take advantage of all the
--   Producer-related utilities that Pipes.Prelude has to
--   offer.
--   
--   
--   
- To lift a plain list into a ListT computation, first apply
--   each to turn the list into a Producer. Then apply the
--   Select constructor to convert from Producer to
--   ListT.
--   
- For other ways to construct ListT computations, see the
--   “Producers” section in Pipes.Prelude to build Producers.
--   These can then be converted to ListT using Select.
--   
- To aggregate the values from a ListT computation (for
--   example, to compute the sum of a ListT of numbers), first apply
--   enumerate to obtain a Producer. Then see the “Folds”
--   section in Pipes.Prelude to proceed.
--   
newtype ListT m a
Select :: Producer a m () -> ListT m a
[enumerate] :: ListT m a -> Producer a m ()

-- | Run a self-contained ListT computation
runListT :: Monad m => ListT m a -> m ()

-- | Enumerable generalizes Foldable, converting effectful
--   containers to ListTs.
--   
--   Instances of Enumerable must satisfy these two laws:
--   
--   
--   toListT (return r) = return r
--   
--   toListT $ do x <- m  =  do x <- toListT m
--                f x           toListT (f x)
--   
--   
--   In other words, toListT is monad morphism.
class Enumerable t
toListT :: (Enumerable t, Monad m) => t m a -> ListT m a

-- | Consume the first value from a Producer
--   
--   next either fails with a Left if the Producer
--   terminates or succeeds with a Right providing the next value
--   and the remainder of the Producer.
next :: Monad m => Producer a m r -> m (Either r (a, Producer a m r))

-- | Convert a Foldable to a Producer
--   
--   
--   each :: (Functor m, Foldable f) => f a -> Producer a m ()
--   
each :: (Functor m, Foldable f) => f a -> Proxy x' x () a m ()

-- | Convert an Enumerable to a Producer
--   
--   
--   every :: (Monad m, Enumerable t) => t m a -> Producer a m ()
--   
every :: (Monad m, Enumerable t) => t m a -> Proxy x' x () a m ()

-- | Discards a value
discard :: Monad m => a -> m ()

-- | Monads that also support choice and failure.
class (Alternative m, Monad m) => MonadPlus (m :: Type -> Type)

-- | The identity of mplus. It should also satisfy the equations
--   
--   
--   mzero >>= f  =  mzero
--   v >> mzero   =  mzero
--   
--   
--   The default definition is
--   
--   
--   mzero = empty
--   
mzero :: MonadPlus m => m a

-- | An associative operation. The default definition is
--   
--   
--   mplus = (<|>)
--   
mplus :: MonadPlus m => m a -> m a -> m a

-- | void value discards or ignores the result of
--   evaluation, such as the return value of an IO action.
--   
--   
Examples
--   
--   Replace the contents of a Maybe Int with unit:
--   
--   
--   >>> void Nothing
--   Nothing
--   
--   >>> void (Just 3)
--   Just ()
--   
--   
--   Replace the contents of an Either Int
--   Int with unit, resulting in an Either
--   Int ():
--   
--   
--   >>> void (Left 8675309)
--   Left 8675309
--   
--   >>> void (Right 8675309)
--   Right ()
--   
--   
--   Replace every element of a list with unit:
--   
--   
--   >>> void [1,2,3]
--   [(),(),()]
--   
--   
--   Replace the second element of a pair with unit:
--   
--   
--   >>> void (1,2)
--   (1,())
--   
--   
--   Discard the result of an IO action:
--   
--   
--   >>> mapM print [1,2]
--   1
--   2
--   [(),()]
--   
--   >>> void $ mapM print [1,2]
--   1
--   2
--   
void :: Functor f => f a -> f ()

-- | Monads in which IO computations may be embedded. Any monad
--   built by applying a sequence of monad transformers to the IO
--   monad will be an instance of this class.
--   
--   Instances should satisfy the following laws, which state that
--   liftIO is a transformer of monads:
--   
--   
--   
- 
liftIO . return = return

--   
- 
liftIO (m >>= f) = liftIO m >>=
--   (liftIO . f)

--   
class Monad m => MonadIO (m :: Type -> Type)

-- | Lift a computation from the IO monad. This allows us to run IO
--   computations in any monadic stack, so long as it supports these kinds
--   of operations (i.e. IO is the base monad for the stack).
--   
--   
Example
--   
--   
--   import Control.Monad.Trans.State -- from the "transformers" library
--   
--   printState :: Show s => StateT s IO ()
--   printState = do
--     state <- get
--     liftIO $ print state
--   
--   
--   Had we omitted liftIO, we would have ended up with
--   this error:
--   
--   
--   • Couldn't match type ‘IO’ with ‘StateT s IO’
--    Expected type: StateT s IO ()
--      Actual type: IO ()
--   
--   
--   The important part here is the mismatch between StateT s IO
--   () and IO ().
--   
--   Luckily, we know of a function that takes an IO a and
--   returns an (m a): liftIO, enabling us to run
--   the program and see the expected results:
--   
--   
--   > evalStateT printState "hello"
--   "hello"
--   
--   > evalStateT printState 3
--   3
--   
liftIO :: MonadIO m => IO a -> m a

-- | The class of monad transformers. Instances should satisfy the
--   following laws, which state that lift is a monad
--   transformation:
--   
--   
--   
- 
lift . return = return

--   
- 
lift (m >>= f) = lift m >>=
--   (lift . f)

--   
class () => MonadTrans (t :: Type -> Type -> Type -> Type)

-- | Lift a computation from the argument monad to the constructed monad.
lift :: (MonadTrans t, Monad m) => m a -> t m a

-- | A monad in the category of monads, using lift from
--   MonadTrans as the analog of return and embed as
--   the analog of (=<<):
--   
--   
--   embed lift = id
--   
--   embed f (lift m) = f m
--   
--   embed g (embed f t) = embed (\m -> embed g (f m)) t
--   
class (MFunctor t, MonadTrans t) => MMonad (t :: Type -> Type -> Type -> Type)

-- | Embed a newly created MMonad layer within an existing layer
--   
--   embed is analogous to (=<<)
embed :: forall (n :: Type -> Type) m b. (MMonad t, Monad n) => (forall a. () => m a -> t n a) -> t m b -> t n b

-- | A functor in the category of monads, using hoist as the analog
--   of fmap:
--   
--   
--   hoist (f . g) = hoist f . hoist g
--   
--   hoist id = id
--   
class () => MFunctor (t :: Type -> Type -> k -> Type)

-- | Lift a monad morphism from m to n into a monad
--   morphism from (t m) to (t n)
--   
--   The first argument to hoist must be a monad morphism, even
--   though the type system does not enforce this
hoist :: forall m n (b :: k). (MFunctor t, Monad m) => (forall a. () => m a -> n a) -> t m b -> t n b

-- | The Foldable class represents data structures that can be reduced to a
--   summary value one element at a time. Strict left-associative folds are
--   a good fit for space-efficient reduction, while lazy right-associative
--   folds are a good fit for corecursive iteration, or for folds that
--   short-circuit after processing an initial subsequence of the
--   structure's elements.
--   
--   Instances can be derived automatically by enabling the
--   DeriveFoldable extension. For example, a derived instance for
--   a binary tree might be:
--   
--   
--   {-# LANGUAGE DeriveFoldable #-}
--   data Tree a = Empty
--               | Leaf a
--               | Node (Tree a) a (Tree a)
--       deriving Foldable
--   
--   
--   A more detailed description can be found in the Overview
--   section of Data.Foldable#overview.
--   
--   For the class laws see the Laws section of
--   Data.Foldable#laws.
class () => Foldable (t :: Type -> Type)
instance Pipes.Enumerable Pipes.ListT
instance Pipes.Enumerable Control.Monad.Trans.Identity.IdentityT
instance Pipes.Enumerable Control.Monad.Trans.Maybe.MaybeT
instance Pipes.Enumerable (Control.Monad.Trans.Except.ExceptT e)
instance GHC.Base.Functor m => GHC.Base.Functor (Pipes.ListT m)
instance GHC.Base.Functor m => GHC.Base.Applicative (Pipes.ListT m)
instance GHC.Base.Monad m => GHC.Base.Monad (Pipes.ListT m)
instance GHC.Base.Monad m => Control.Monad.Fail.MonadFail (Pipes.ListT m)
instance Data.Foldable.Foldable m => Data.Foldable.Foldable (Pipes.ListT m)
instance (GHC.Base.Functor m, Data.Traversable.Traversable m) => Data.Traversable.Traversable (Pipes.ListT m)
instance Control.Monad.Trans.Class.MonadTrans Pipes.ListT
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Pipes.ListT m)
instance GHC.Base.Functor m => GHC.Base.Alternative (Pipes.ListT m)
instance GHC.Base.Monad m => GHC.Base.MonadPlus (Pipes.ListT m)
instance Control.Monad.Morph.MFunctor Pipes.ListT
instance Control.Monad.Morph.MMonad Pipes.ListT
instance GHC.Base.Functor m => GHC.Base.Semigroup (Pipes.ListT m a)
instance GHC.Base.Functor m => GHC.Base.Monoid (Pipes.ListT m a)
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Pipes.ListT m)
instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Pipes.ListT m)
instance Control.Monad.Reader.Class.MonadReader i m => Control.Monad.Reader.Class.MonadReader i (Pipes.ListT m)
instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Pipes.ListT m)
instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Pipes.ListT m)
instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Pipes.ListT m)
instance GHC.Base.Monad m => Control.Monad.Zip.MonadZip (Pipes.ListT m)

-- | Many actions in base monad transformers cannot be automatically
--   lifted. These functions lift these remaining actions so that
--   they work in the Proxy monad transformer.
--   
--   See the mini-tutorial at the bottom of this module for example code
--   and typical use cases where this module will come in handy.
module Pipes.Lift

-- | Distribute Proxy over a monad transformer
distribute :: (Monad m, MonadTrans t, MFunctor t, Monad (t m), Monad (t (Proxy a' a b' b m))) => Proxy a' a b' b (t m) r -> t (Proxy a' a b' b m) r

-- | Wrap the base monad in ExceptT
exceptP :: Monad m => Proxy a' a b' b m (Either e r) -> Proxy a' a b' b (ExceptT e m) r

-- | Run ExceptT in the base monad
runExceptP :: Monad m => Proxy a' a b' b (ExceptT e m) r -> Proxy a' a b' b m (Either e r)

-- | Catch an error in the base monad
catchError :: Monad m => Proxy a' a b' b (ExceptT e m) r -> (e -> Proxy a' a b' b (ExceptT e m) r) -> Proxy a' a b' b (ExceptT e m) r

-- | Catch an error using a catch function for the base monad
liftCatchError :: Monad m => (m (Proxy a' a b' b m r) -> (e -> m (Proxy a' a b' b m r)) -> m (Proxy a' a b' b m r)) -> Proxy a' a b' b m r -> (e -> Proxy a' a b' b m r) -> Proxy a' a b' b m r

-- | Wrap the base monad in MaybeT
maybeP :: Monad m => Proxy a' a b' b m (Maybe r) -> Proxy a' a b' b (MaybeT m) r

-- | Run MaybeT in the base monad
runMaybeP :: Monad m => Proxy a' a b' b (MaybeT m) r -> Proxy a' a b' b m (Maybe r)

-- | Wrap the base monad in ReaderT
readerP :: Monad m => (i -> Proxy a' a b' b m r) -> Proxy a' a b' b (ReaderT i m) r

-- | Run ReaderT in the base monad
runReaderP :: Monad m => i -> Proxy a' a b' b (ReaderT i m) r -> Proxy a' a b' b m r

-- | Wrap the base monad in StateT
stateP :: Monad m => (s -> Proxy a' a b' b m (r, s)) -> Proxy a' a b' b (StateT s m) r

-- | Run StateT in the base monad
runStateP :: Monad m => s -> Proxy a' a b' b (StateT s m) r -> Proxy a' a b' b m (r, s)

-- | Evaluate StateT in the base monad
evalStateP :: Monad m => s -> Proxy a' a b' b (StateT s m) r -> Proxy a' a b' b m r

-- | Execute StateT in the base monad
execStateP :: Monad m => s -> Proxy a' a b' b (StateT s m) r -> Proxy a' a b' b m s

-- | Wrap the base monad in WriterT
writerP :: (Monad m, Monoid w) => Proxy a' a b' b m (r, w) -> Proxy a' a b' b (WriterT w m) r

-- | Run WriterT in the base monad
runWriterP :: (Monad m, Monoid w) => Proxy a' a b' b (WriterT w m) r -> Proxy a' a b' b m (r, w)

-- | Execute WriterT in the base monad
execWriterP :: (Monad m, Monoid w) => Proxy a' a b' b (WriterT w m) r -> Proxy a' a b' b m w

-- | Wrap the base monad in RWST
rwsP :: (Monad m, Monoid w) => (i -> s -> Proxy a' a b' b m (r, s, w)) -> Proxy a' a b' b (RWST i w s m) r

-- | Run RWST in the base monad
runRWSP :: (Monad m, Monoid w) => r -> s -> Proxy a' a b' b (RWST r w s m) d -> Proxy a' a b' b m (d, s, w)

-- | Evaluate RWST in the base monad
evalRWSP :: (Monad m, Monoid w) => r -> s -> Proxy a' a b' b (RWST r w s m) d -> Proxy a' a b' b m (d, w)

-- | Execute RWST in the base monad
execRWSP :: (Monad m, Monoid w) => r -> s -> Proxy a' a b' b (RWST r w s m) d -> Proxy a' a b' b m (s, w)

-- | General purpose utilities
--   
--   The names in this module clash heavily with the Haskell Prelude, so I
--   recommend the following import scheme:
--   
--   
--   import Pipes
--   import qualified Pipes.Prelude as P  -- or use any other qualifier you prefer
--   
--   
--   Note that String-based IO is inefficient. The
--   String-based utilities in this module exist only for simple
--   demonstrations without incurring a dependency on the text
--   package.
--   
--   Also, stdinLn and stdoutLn remove and add newlines,
--   respectively. This behavior is intended to simplify examples. The
--   corresponding stdin and stdout utilities from
--   pipes-bytestring and pipes-text preserve newlines.
module Pipes.Prelude

-- | Read Strings from stdin using getLine
--   
--   Terminates on end of input
stdinLn :: MonadIO m => Producer' String m ()

-- | read values from stdin, ignoring failed parses
readLn :: (MonadIO m, Read a) => Producer' a m ()

-- | Read Strings from a Handle using hGetLine
--   
--   Terminates on end of input
--   
--   
--   fromHandle :: MonadIO m => Handle -> Producer String m ()
--   
fromHandle :: MonadIO m => Handle -> Proxy x' x () String m ()

-- | Repeat a monadic action indefinitely, yielding each result
--   
--   repeatM :: Monad m => m a -> Producer a m r
repeatM :: Monad m => m a -> Proxy x' x () a m r

-- | Repeat a monadic action a fixed number of times, yielding each
--   result
--   
--   
--   replicateM  0      x = return ()
--   
--   replicateM (m + n) x = replicateM m x >> replicateM n x  -- 0 <= {m,n}
--   
--   
--   
--   replicateM :: Monad m => Int -> m a -> Producer a m ()
--   
replicateM :: Monad m => Int -> m a -> Proxy x' x () a m ()

-- | The natural unfold into a Producer with a step function and a
--   seed
--   
--   
--   unfoldr next = id
--   
unfoldr :: Monad m => (s -> m (Either r (a, s))) -> s -> Producer a m r

-- | Write Strings to stdout using putStrLn
--   
--   Unlike toHandle, stdoutLn gracefully terminates on a
--   broken output pipe
stdoutLn :: MonadIO m => Consumer' String m ()

-- | Write Strings to stdout using putStrLn
--   
--   This does not handle a broken output pipe, but has a polymorphic
--   return value
stdoutLn' :: MonadIO m => Consumer' String m r

-- | Consume all values using a monadic function
mapM_ :: Monad m => (a -> m ()) -> Consumer' a m r

-- | print values to stdout
print :: (MonadIO m, Show a) => Consumer' a m r

-- | Write Strings to a Handle using hPutStrLn
toHandle :: MonadIO m => Handle -> Consumer' String m r

-- | discard all incoming values
drain :: Functor m => Consumer' a m r

-- | Apply a function to all values flowing downstream
--   
--   
--   map id = cat
--   
--   map (g . f) = map f >-> map g
--   
map :: Functor m => (a -> b) -> Pipe a b m r

-- | Apply a monadic function to all values flowing downstream
--   
--   
--   mapM return = cat
--   
--   mapM (f >=> g) = mapM f >-> mapM g
--   
mapM :: Monad m => (a -> m b) -> Pipe a b m r

-- | Convert a stream of actions to a stream of values
sequence :: Monad m => Pipe (m a) a m r

-- | Apply a function to all values flowing downstream, and forward each
--   element of the result.
mapFoldable :: (Functor m, Foldable t) => (a -> t b) -> Pipe a b m r

-- | (filter predicate) only forwards values that satisfy the
--   predicate.
--   
--   
--   filter (pure True) = cat
--   
--   filter (liftA2 (&&) p1 p2) = filter p1 >-> filter p2
--   
--   filter f = mapMaybe (\a -> a <$ guard (f a))
--   
filter :: Functor m => (a -> Bool) -> Pipe a a m r

-- | (mapMaybe f) yields Just results of f.
--   
--   Basic laws:
--   
--   
--   mapMaybe (f >=> g) = mapMaybe f >-> mapMaybe g
--   
--   mapMaybe (pure @Maybe . f) = mapMaybe (Just . f) = map f
--   
--   mapMaybe (const Nothing) = drain
--   
--   
--   As a result of the second law,
--   
--   
--   mapMaybe return = mapMaybe Just = cat
--   
mapMaybe :: Functor m => (a -> Maybe b) -> Pipe a b m r

-- | (filterM predicate) only forwards values that satisfy the
--   monadic predicate
--   
--   
--   filterM (pure (pure True)) = cat
--   
--   filterM (liftA2 (liftA2 (&&)) p1 p2) = filterM p1 >-> filterM p2
--   
--   filterM f = wither (\a -> (\b -> a <$ guard b) <$> f a)
--   
filterM :: Monad m => (a -> m Bool) -> Pipe a a m r

-- | (wither f) forwards Just values produced by the
--   monadic action.
--   
--   Basic laws:
--   
--   
--   wither (runMaybeT . (MaybeT . f >=> MaybeT . g)) = wither f >-> wither g
--   
--   wither (runMaybeT . lift . f) = wither (fmap Just . f) = mapM f
--   
--   wither (pure . f) = mapMaybe f
--   
--   
--   As a result of the second law,
--   
--   
--   wither (runMaybeT . return) = cat
--   
--   
--   As a result of the third law,
--   
--   
--   wither (pure . const Nothing) = wither (const (pure Nothing)) = drain
--   
wither :: Monad m => (a -> m (Maybe b)) -> Pipe a b m r

-- | (take n) only allows n values to pass through
--   
--   
--   take 0 = return ()
--   
--   take (m + n) = take m >> take n
--   
--   
--   
--   take <infinity> = cat
--   
--   take (min m n) = take m >-> take n
--   
take :: Functor m => Int -> Pipe a a m ()

-- | (takeWhile p) allows values to pass downstream so long as
--   they satisfy the predicate p.
--   
--   
--   takeWhile (pure True) = cat
--   
--   takeWhile (liftA2 (&&) p1 p2) = takeWhile p1 >-> takeWhile p2
--   
takeWhile :: Functor m => (a -> Bool) -> Pipe a a m ()

-- | (takeWhile' p) is a version of takeWhile that returns the
--   value failing the predicate.
--   
--   
--   takeWhile' (pure True) = cat
--   
--   takeWhile' (liftA2 (&&) p1 p2) = takeWhile' p1 >-> takeWhile' p2
--   
takeWhile' :: Functor m => (a -> Bool) -> Pipe a a m a

-- | (drop n) discards n values going downstream
--   
--   
--   drop 0 = cat
--   
--   drop (m + n) = drop m >-> drop n
--   
drop :: Functor m => Int -> Pipe a a m r

-- | (dropWhile p) discards values going downstream until one
--   violates the predicate p.
--   
--   
--   dropWhile (pure False) = cat
--   
--   dropWhile (liftA2 (||) p1 p2) = dropWhile p1 >-> dropWhile p2
--   
dropWhile :: Functor m => (a -> Bool) -> Pipe a a m r

-- | Flatten all Foldable elements flowing downstream
concat :: (Functor m, Foldable f) => Pipe (f a) a m r

-- | Outputs the indices of all elements that match the given element
elemIndices :: (Functor m, Eq a) => a -> Pipe a Int m r

-- | Outputs the indices of all elements that satisfied the predicate
findIndices :: Functor m => (a -> Bool) -> Pipe a Int m r

-- | Strict left scan
--   
--   
--   Control.Foldl.purely scan :: Monad m => Fold a b -> Pipe a b m r
--   
scan :: Functor m => (x -> a -> x) -> x -> (x -> b) -> Pipe a b m r

-- | Strict, monadic left scan
--   
--   
--   Control.Foldl.impurely scanM :: Monad m => FoldM m a b -> Pipe a b m r
--   
scanM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Pipe a b m r

-- | Apply an action to all values flowing downstream
--   
--   
--   chain (pure (return ())) = cat
--   
--   chain (liftA2 (>>) m1 m2) = chain m1 >-> chain m2
--   
chain :: Monad m => (a -> m ()) -> Pipe a a m r

-- | Parse Readable values, only forwarding the value if the parse
--   succeeds
read :: (Functor m, Read a) => Pipe String a m r

-- | Convert Showable values to Strings
show :: (Functor m, Show a) => Pipe a String m r

-- | Evaluate all values flowing downstream to WHNF
seq :: Functor m => Pipe a a m r

-- | Create a Pipe from a ListT transformation
--   
--   
--   loop (k1 >=> k2) = loop k1 >-> loop k2
--   
--   loop return = cat
--   
loop :: Monad m => (a -> ListT m b) -> Pipe a b m r

-- | Strict fold of the elements of a Producer
--   
--   
--   Control.Foldl.purely fold :: Monad m => Fold a b -> Producer a m () -> m b
--   
fold :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Producer a m () -> m b

-- | Strict fold of the elements of a Producer that preserves the
--   return value
--   
--   
--   Control.Foldl.purely fold' :: Monad m => Fold a b -> Producer a m r -> m (b, r)
--   
fold' :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Producer a m r -> m (b, r)

-- | Strict, monadic fold of the elements of a Producer
--   
--   
--   Control.Foldl.impurely foldM :: Monad m => FoldM a b -> Producer a m () -> m b
--   
foldM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Producer a m () -> m b

-- | Strict, monadic fold of the elements of a Producer
--   
--   
--   Control.Foldl.impurely foldM' :: Monad m => FoldM a b -> Producer a m r -> m (b, r)
--   
foldM' :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Producer a m r -> m (b, r)

-- | (all predicate p) determines whether all the elements of
--   p satisfy the predicate.
all :: Monad m => (a -> Bool) -> Producer a m () -> m Bool

-- | (any predicate p) determines whether any element of
--   p satisfies the predicate.
any :: Monad m => (a -> Bool) -> Producer a m () -> m Bool

-- | Determines whether all elements are True
and :: Monad m => Producer Bool m () -> m Bool

-- | Determines whether any element is True
or :: Monad m => Producer Bool m () -> m Bool

-- | (elem a p) returns True if p has an element
--   equal to a, False otherwise
elem :: (Monad m, Eq a) => a -> Producer a m () -> m Bool

-- | (notElem a) returns False if p has an element
--   equal to a, True otherwise
notElem :: (Monad m, Eq a) => a -> Producer a m () -> m Bool

-- | Find the first element of a Producer that satisfies the
--   predicate
find :: Monad m => (a -> Bool) -> Producer a m () -> m (Maybe a)

-- | Find the index of the first element of a Producer that
--   satisfies the predicate
findIndex :: Monad m => (a -> Bool) -> Producer a m () -> m (Maybe Int)

-- | Retrieve the first element from a Producer
head :: Monad m => Producer a m () -> m (Maybe a)

-- | Index into a Producer
index :: Monad m => Int -> Producer a m () -> m (Maybe a)

-- | Retrieve the last element from a Producer
last :: Monad m => Producer a m () -> m (Maybe a)

-- | Count the number of elements in a Producer
length :: Monad m => Producer a m () -> m Int

-- | Find the maximum element of a Producer
maximum :: (Monad m, Ord a) => Producer a m () -> m (Maybe a)

-- | Find the minimum element of a Producer
minimum :: (Monad m, Ord a) => Producer a m () -> m (Maybe a)

-- | Determine if a Producer is empty
null :: Monad m => Producer a m () -> m Bool

-- | Compute the sum of the elements of a Producer
sum :: (Monad m, Num a) => Producer a m () -> m a

-- | Compute the product of the elements of a Producer
product :: (Monad m, Num a) => Producer a m () -> m a

-- | Convert a pure Producer into a list
toList :: Producer a Identity () -> [a]

-- | Convert an effectful Producer into a list
--   
--   Note: toListM is not an idiomatic use of pipes, but I
--   provide it for simple testing purposes. Idiomatic pipes style
--   consumes the elements immediately as they are generated instead of
--   loading all elements into memory.
toListM :: Monad m => Producer a m () -> m [a]

-- | Convert an effectful Producer into a list alongside the return
--   value
--   
--   Note: toListM' is not an idiomatic use of pipes, but I
--   provide it for simple testing purposes. Idiomatic pipes style
--   consumes the elements immediately as they are generated instead of
--   loading all elements into memory.
toListM' :: Monad m => Producer a m r -> m ([a], r)

-- | Zip two Producers
zip :: Monad m => Producer a m r -> Producer b m r -> Proxy x' x () (a, b) m r

-- | Zip two Producers using the provided combining function
zipWith :: Monad m => (a -> b -> c) -> Producer a m r -> Producer b m r -> Proxy x' x () c m r

-- | Transform a Consumer to a Pipe that reforwards all
--   values further downstream
tee :: Monad m => Consumer a m r -> Pipe a a m r

-- | Transform a unidirectional Pipe to a bidirectional Proxy
--   
--   
--   generalize (f >-> g) = generalize f >+> generalize g
--   
--   generalize cat = pull
--   
generalize :: Monad m => Pipe a b m r -> x -> Proxy x a x b m r

-- | Conventional Haskell stream programming forces you to choose only two
--   of the following three features:
--   
--   
--   
- Effects
--   
- Streaming
--   
- Composability
--   
--   
--   If you sacrifice Effects you get Haskell's pure and lazy lists,
--   which you can transform using composable functions in constant space,
--   but without interleaving effects.
--   
--   If you sacrifice Streaming you get mapM, forM and
--   "ListT done wrong", which are composable and effectful, but do not
--   return a single result until the whole list has first been processed
--   and loaded into memory.
--   
--   If you sacrifice Composability you write a tightly coupled
--   read, transform, and write loop in IO, which is streaming and
--   effectful, but is not modular or separable.
--   
--   pipes gives you all three features: effectful, streaming, and
--   composable programming. pipes also provides a wide variety of
--   stream programming abstractions which are all subsets of a single
--   unified machinery:
--   
--   
--   
- effectful Producers (like generators),
--   
- effectful Consumers (like iteratees),
--   
- effectful Pipes (like Unix pipes), and:
--   
- ListT done right.
--   
--   
--   All of these are connectable and you can combine them together in
--   clever and unexpected ways because they all share the same underlying
--   type.
--   
--   pipes requires a basic understanding of monad transformers,
--   which you can learn about by reading either:
--   
--   
--   
- the paper "Monad Transformers - Step by Step",
--   
- part III "Monads in the Real World" of the tutorial "All About
--   Monads",
--   
- chapter 18 of "Real World Haskell" on monad transformers, or:
--   
- the documentation of the transformers library.
--   
--   
--   If you want a Quick Start guide to pipes, read the
--   documentation in Pipes.Prelude from top to bottom.
--   
--   This tutorial is more extensive and explains the pipes API in
--   greater detail and illustrates several idioms.
module Pipes.Tutorial
