
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 values. 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: http://matt.immute.net/content/pointless-fun Questions: 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? Thanks! Matt [1] http://conal.net/blog/posts/semantic-editor-combinators/ [2] http://conal.net/blog/posts/prettier-functions-for-wrapping-and-wrapping/