
Paolo Capriotti wrote:
I'm pleased to announce the release of version 0.1.0 of pipes-core, a library for efficient, safe and compositional IO, similar in scope to iteratee and conduits.
I like your pipes package. This is very similar to what Mario Blažević wrote about his Coroutines in the Monad.Reader (can't remember which issue; great article, BTW, many thanks Mario for making me understand the iteratee business (and also generators) for the first time). Your pipes-core looks even simpler to use, maybe due to avoiding to make a type distinction between consumer/producer/pipe (except the natural one i.e. through the input/output types), even though the parameterization by a functor (as in Monad.Coroutine) has its own beauty. Two issues: (1) What is the reason for the asymmetry in type Producer b m = Pipe () b m type Consumer a m = Pipe a Void m i.e. why does Producer use () for the input? I would expect it to use Void, like Consumer does for its output. Calling await in a Producer resulting in an immediate 'return ()' as you say is allowed (in the tutorial) strikes me as not very useful. If the idea is simply to flag nonsense like consumer >+> producer with a type error, then it might be a better idea to introduce two different Void types: data NoOutput data NoInput type Producer b m = Pipe NoInput b m type Consumer a m = Pipe a NoOutput m type Pipeline m = Pipe NoInput NoOutput m (and isn't this nicely self-explaining?) (2) The $$ operator is poorly named. I would intuitively expect an operator that looks so similar to the standard $ to have the same direction of data flow (i.e. right to left, like function application and composition) but your is left to right. You could use e.g. >$> instead, which has the additional advantage of allowing a symmetric variant for the other direction i.e. <$<. Cheers Ben