A collection of useful common processes that are useful when plumbing
together a process network. All the processes here rethrow poison when
it is encountered, as this gives the user maximum flexibility (they can
let it propagate it, or ignore it).

The names here overlap with standard Prelude names. This is
deliberate, as the processes act in a similar manner to the
corresponding Prelude versions. It is expected that you will do
something like:

A process that waits for an input, then sends it out on all its output
channels (in order) during an extended rendezvous. This is often used to send the
output on to both the normal recipient (without introducing buffering) and
also to a listener process that wants to examine the value. If the listener
process is first in the list, and does not take the input immediately, the
value will not be sent to the other recipients until it does. The name
of the process derives from the notion of a wire-tap, since the listener
is hidden from the other processes (it does not visibly change the semantics
for them -- except when the readers of the channels are offering a choice).

Forever reads in a value, transforms it using the given function, and sends it
out again. Note that the transformation is not applied strictly, so don't
assume that this process will actually perform the computation. If you
require a strict transformation, use map'.

Streams all items in a Data.Traversable.Traversable container out
in the order given by Data.Traversable.mapM on the output channel (one at
a time). Lists, Maybe, and Data.Set.Set are all instances
of Data.Traversable.Traversable, so this can be used for all of
those.

For the duration of the given process, acts as a consume process, but stops
when the given process stops. Note that there could be a timing issue where
extra inputs are consumed at the end of the lifetime of the process.
Note also that while poison from the given process will be propagated on the
consumption channel, there is no mechanism to propagate poison from the consumption
channel into the given process.

Forever reads a value from both its input channels in parallel, then joins
the two values using the given function and sends them out again. For example,
join (,) c d will pair the values read from c and d and send out the
pair on the output channel, whereas join (&&) will send out the conjunction
of two boolean values, join (==) will read two values and output whether
they are equal or not, etc.

A sorter process. When it receives its first Just x data item, it keeps
it. When it receieves a second, it keeps the lowest of the two, and sends
out the other one. When it receives Nothing, it sends out its data value,
then sends Nothing too. The overall effect when chaining these things together
is a sorting pump. You inject all the values with Just, then send in a
single Nothing to get the results out (in reverse order).