[   ^ to index...   |   <-- previous   |   next -->   ]

Currying

Named after the mathematician Haskell Curry, "currying" is a way of defining functions of multiple arguments in terms of higher-order functions, each of which takes a single argument and returns a higher order function.

The key insight of currying: Any function of type

a * b -> c

can also be phrased as a function of type

a -> b -> c

Consider normal addition:

val add = fn (x, y) => x + y;
val foo = add(3, 4);

This can also be viewed as:

val handCurriedAdd = fn (x) => fn(y) => x + y;
val addFive   = handCurriedAdd 5;       (* adds 5 to any int *)
val eleven    = addFive 6;              (* applying addFive *)
val seventeen = (handCurriedAdd 8) 9;   (* applying both at once *)
val twenty    = handCurriedAdd 10 10;   (* application is left-associative *)

Note that handCurriedAdd is identical to makeAddX from the previous page. Since manually currying functions is tedious, ML provides a convenient syntax for currying:

fun curriedAdd x y = x + y;
val thirty = curriedAdd 15 15;

Of course, these examples are pretty trivial. But consider what we can do if we curry qsort:

(* Curried definition: notice no comma between params *)
fun qsort (greaterThan:('a * 'a) -> bool) (elems:'a list) = ...

(* Not taking advantage of currying.  Not so cool. *)
fun sortComplexByReal elems = qsort (sortBy(RealPart)) elems);

(* Here, we really take advantage of curried syntax *) 
val sortComplexByImag = qsort (sortBy(RealPart));

Incidentally, here we I am showing you currying as a matter of convenience in syntax. However, it's a profound idea that a function of multiple arguments can be conceptually partially evaluated to produce a function that does "the rest of the computation".

Currying in the ML standard library

The ML standard libraries use currying extensively. Here are a couple of function type signatures from the List structure:

val filter : ('a -> bool) -> 'a list -> 'a list
val exists : ('a -> bool) -> 'a list -> bool

Keunwoo Lee
Last modified: Thu Apr 26 10:42:42 PDT 2001