A clearer point-free style

Conal Elliott has been explaining (1, 2) what he calls semantic editor combinators, which I've also seen referred to as (fmap.fmap) style. It's great stuff. Simple, clear, and a big payoff. For a long time, I've wanted a better (read: clearer) way of transforming arguments of curried functions. Arrow combinators never quite seemed to fit the bill, focusing as they do on pairs, and sections of (.) are just too cryptic for me.

As an example, suppose we didn't have Data.Ord.comparing, but only compare. If we want to compare lists by length, say, we can now write:

argument length . (result.argument) length $ compare

which I actually find reasonably clear. Now it's easy, for example, to transform just the third argument of a curried function. Very cool. (In complicated cases, we'll quickly want a family of combinators like cadddr, cdadr, etc., but there are worse things...)

In common cases like compare, though, where we really want to transform a whole series of arguments, one would really love a class like Applicative to do the trick:

compare <$> length <*> length ==
  \x y -> compare (length x) (length y)

Of course that doesn't work, but it would be really nice to be able to write this kind of composition in a similar applicative style.

Is it possible to write a type class to do this? Has someone done it?

Tags: