[Haskell-cafe] Gluing pipes

Matt Hellige matt at immute.net
Thu Dec 4 13:07:06 EST 2008

On Thu, Dec 4, 2008 at 11:19 AM, Dan Piponi <dpiponi at gmail.com> wrote:
> On Wed, Dec 3, 2008 at 10:17 AM, Matt Hellige <matt at immute.net> wrote:
>> >From time to time, I've wanted to have a more pleasant way of writing
>> point-free compositions of curried functions.
>> I'd like to be able to write something like:
>>  \ x y -> f (g x) (h y)
> This particular composition of f with g and h is an example of
> composition in what mathematicians call an operad. I think operads
> glue things just how you want. Unfortunately (1) I don't think
> mathematicians have great notation for it either and (2) it's hard to
> combine operads with currying because they rely on having a well
> defined notion of the number of arguments of a function.

Yes, of course I should have mentioned operads! I've thought of
operads in connection with this puzzle before (and I seem to remember
a recent post from you on the subject), but this time around, it
slipped my mind... Thanks for the reminder!

Something like operadic composition for curried functions is exactly
what I want to define, and I agree that your (1) and (2) are exactly
the sticking points. I'm relatively happy with what I've come up with
so far, but I do still wonder if it's possible to do better. An
alternative approach would be to define an Operad type class, and
attempt to coax curried functions into and out of an instance as
needed. I hesitate to propose that it's impossible, but I guess it
would take type class hacking beyond my abilities in any case.

We could imagine being able to write something like:
  f [g, h]
and I think this is the route you took in your blog post? But of
course your way only works for uncurried functions, right? And there's
a bit of boilerplate? I also believe that this approach would leave at
least some arity checking to runtime, which I would consider a
shortcoming. Perhaps it would be possible to overcome this with
length-indexed lists?

Finally, there's a further disadvantage to both of these approaches:
it seems to me that neither approach allows us to "cross pipes". For
instance, we can't define flip using these techniques, or any "deep
  \ x y z -> f x z y
Is it true in general that operads cannot express pipe-crossing
compositions? Or is it just a shortcoming of this particular
implementation? Of course this is getting farther afield, and I don't
believe that my approach can express this either.

Anyway I'd still love to know the answers the questions in my last
email, as well as the new questions posed in this one. ;)

Thanks for taking the time!

More information about the Haskell-Cafe mailing list