Multi-Output Conduits?

In my last two posts I've been looking at ways to extend the conduit library to create conduits with 2 inputs and conduits with more than 2 inputs. One might wonder, then, about conduits with multiple outputs. I have found that multi-outuput conduits are much less interesting than multi-input conduits, and I want to explain why.

For multi-input conduits, we have await, lift await, and so on to take input from one input stream and leave the others undisturbed. This lets you say

I need an i1, not an i2, before I go any further.

Closely related to this is a 1-input conduit which takes an Either i1 i2 input. This lets you say

I need either an i1 or an i2, before I go any further.

Now lets consider these two strategies applied to the output side. We can have a nested, two-output conduit and use yield and lift yield. Then yield says

I have an o1, but no o2. You have to take it before I go any further.

If instead we have a 1-output conduit which gives values of type Either o1 o2, we can use yield Left and yield Right. Then yield Left says the same thing again!

I have an o1, but no o2. You have to take it before I go any further.

Whats going on here? When we have multiple input streams, we are assuming the streams are independent. If the input streams were coupled together in some way, then taking 1000 values from the first input without taking anything from the second input might cause memory leaks or worse. When we have two different output "streams", they are most certainly not independent. Anything trying to use these values better take them from the right stream at the right time or something bad will happen.

If 2-output conduits are allowed, one might naturally want to connect the two output conduits of A to the two input conduits of B. But this can lead to nonsensical situations, like A yielding on output 1 while B is awaiting on input 2:


So, multiple inputs can be very helpful, and are genuinely more powerful than zipped or Either tagged inputs, but multiple outputs are not worth the trouble. If you just want to send output to multiple sinks, you should use zipSinks.