[Haskell-cafe] Gluing pipes

Matt Hellige matt at immute.net
Wed Dec 3 13:17:59 EST 2008

>From time to time, I've wanted to have a more pleasant way of writing
point-free compositions of curried functions. One might want to
transform both the first and second arguments, for instance, or only
the third argument, of a curried function. I've never known a
(non-cryptic) way to do this.

For example, given:
  f :: a -> b -> c
  g :: a1 -> a
  h :: b2 -> b
I'd like to be able to write something like:
  \ x y -> f (g x) (h y)
in a way that is both point-free and applicative. In other words, I'd
like to apply a function to "pipes" or transformers rather than to

Recent posts by Conal Elliott [1,2] got me thinking about this again,
and I've found a simple solution.

I use two of Conal's combinators:
  argument = flip (.)
  result = (.)

And now we define:
  infixr 2 ~>
  f ~> g = argument f . result g

  infixl 1 $.
  ($.) = flip ($)

Which lets us write:
  -- transform both arguments
  f $. g ~> h ~> id
  -- transform just the second argument
  f $. id ~> h ~> id

The name ($.) is chosen to indicate that this is (roughly) a
composition disguised as an application. The transformer spec to the
right of ($.) looks like the type of the function to the left, and
consists of a transformer for each argument and one for the result
type. Of course, (~>) is right associative, and id can match the
entire tail "in bulk", so we can also write something like:
  f $. g ~> id
And of course, each transformer can be a pipeline, so assuming proper
types, we can do things like:
  f $. id ~> (length.snd.unWrap) ~> wrap

More details here:


1. Is there already another well-known way to do this? It seems a
common enough problem...

2. Do these particular combinators already exist somewhere with other names?

3. Are there better names for these functions?


[1] http://conal.net/blog/posts/semantic-editor-combinators/
[2] http://conal.net/blog/posts/prettier-functions-for-wrapping-and-wrapping/

More information about the Haskell-Cafe mailing list