Types

The underlying datatype for all the types in this package. In has four
type parameters:

i is the type of values for this Pipe's input stream.

o is the type of values for this Pipe's output stream.

m is the underlying monad.

r is the result type.

Note that o and r are inherently different. o is the type of the
stream of values this Pipe will produce and send downstream. r is the
final output of this Pipe.

Pipes can be composed via the pipe function. To do so, the output type
of the left pipe much match the input type of the left pipe, and the result
type of the left pipe must be unit (). This is due to the fact that any
result produced by the left pipe must be discarded in favor of the result of
the right pipe.

Request more input from upstream. The first field takes a new input
value and provides a new Pipe. The second is for early termination. It
gives a new Pipe which takes no input from upstream. This allows a
Pipe to provide a final stream of output values after no more input is
available from upstream.

Require running of a monadic action to get the next Pipe. Second
field is an early cleanup function. Technically, this second field
could be skipped, but doing so would require extra operations to be
performed in some cases. For example, for a Pipe pulling data from a
file, it may be forced to pull an extra, unneeded chunk before closing
the Handle.

A Pipe which provides a stream of output values, without consuming any
input. The input parameter is set to Void to indicate that this Pipe
takes no input. A Source is not used to produce a final result, and thus
the result parameter is set to ().

A Pipe which consumes a stream of input values and produces a final
result. It cannot produce any output values, and thus the output parameter
is set to Void. In other words, it is impossible to create a HaveOutput
constructor for a Sink.

The connect-and-resume operator. Does not close the Source, but instead
returns it to be used again. This allows a Source to be used incrementally
in a large program, without forcing the entire program to live in the Sink
monad.

Convenience re-exports

The Resource transformer. This transformer keeps track of all registered
actions, and calls them upon exit (via runResourceT). Actions may be
registered via register, or resources may be allocated atomically via
allocate. allocate corresponds closely to bracket.

Releasing may be performed before exit via the release function. This is a
highly recommended optimization, as it will ensure that scarce resources are
freed early. Note that calling release will deregister the action, so that
a release action will only ever be called once.

A Monad which allows for safe resource allocation. In theory, any monad
transformer stack included a ResourceT can be an instance of
MonadResource.

Note: runResourceT has a requirement for a MonadBaseControl IO m monad,
which allows control operations to be lifted. A MonadResource does not
have this requirement. This means that transformers such as ContT can be
an instance of MonadResource. However, the ContT wrapper will need to be
unwrapped before calling runResourceT.

A Monad which can throw exceptions. Note that this does not work in a
vanilla ST or Identity monad. Instead, you should use the ExceptionT
transformer in your stack if you are dealing with a non-IO base monad.

Unwrap a ResourceT transformer, and call all registered release actions.

Note that there is some reference counting involved due to resourceForkIO.
If multiple threads are sharing the same collection of resources, only the
last call to runResourceT will deallocate the resources.