Function composition and currying

Dean Herington heringto@cs.unc.edu
Thu, 17 Jul 2003 15:28:45 -0400


Tom Pledger wrote:

> K. Fritz Ruehr writes:
>  :
>  | But Jerzy Karczmarczuk enlightened me as to the full generality possible
>  | along these lines (revealing the whole truth under the influence of at
>  | least one beer, as I recall). Namely, one can define a sequence of
>  | functions (let's use a better notation now, with "c" for composition):
>  |
>  |     c1 = (.)                      -- good old composition
>  |     c2 = (.) . (.)                -- my (.<) from above
>  |     c3 = (.) . (.) . (.)
>  |     c4 = (.) . (.) . (.) . (.)
>  |     -- etc.
>
> Nice!
>
> There's also
>
>     c0 = ($)
>
> which is clearer if you use 'non-pointfree' notation
>
>     ...
>     c2 f g x y = f (g x y)
>     c1 f g x   = f (g x)
>     c0 f g     = f  g
>
> - Tom

Note also that chains of these operators can be used in a somewhat readable
way.  For example, suppose we have:

f1 :: Int -> Int
f2 :: Int -> Int -> Int
f3 :: Int -> Int -> Int -> Int
f  :: Int -> Int -> Int -> Int -> Int
f1 x      = -x
f2 x y    = x - y
f3 x y z  = x * (y - z)
f a b c d = f2 (f1 (f3 a b c)) d

We can define `f` in a point-free style:

f = f2 `c1` f1 `c3` f3

Each function in the composition, from innermost (rightmost) to outermost
(leftmost), takes the intermediate result so far (or, for the innermost
function, the first argument) plus zero or more additional arguments from those
that remain, as determined by the composition operator to its left.  Note that
the composition operators need to be left-associative (as they are by default)
for this to work.

-- Dean