wiki

Currying

Turning a function of several arguments into a function of the first argument that returns a function of the rest: f : A * B -> C becomes curry f : A -> (B -> C). In OCaml and Haskell every function is curried, so applying it to fewer arguments than it takes, partial application, is ordinary.

The two are inverse, and together they are an isomorphism between function spaces:

For finite sets the cardinalities agree, . In category theory this isomorphism, natural in , is what it means to be cartesian closed: , so is left adjoint to .

In OCaml, int -> int -> int is int -> (int -> int).

let curry f a b = f (a, b)
let uncurry f (a, b) = f a b
(* Every OCaml function takes one argument: this is int -> (int -> int). *)
let add a b = a + b
let add_pair (a, b) = a + b
let increment = add 1 (* partial application *)
let add' = curry add_pair (* same type as add *)
let add_pair' = uncurry add (* same type as add_pair *)

Running it.

increment 41 -> 42
add' 2 3, add_pair' (2, 3) -> 5, 5
List.map (add 10) [1; 2; 3] -> [11; 12; 13]

Partial application is what makes combinators like List.map (add 10) short. It does not make ordinary calls slow: the native compiler records each function's arity, a call that supplies all the arguments builds no intermediate closures, and only a partial application allocates one, to hold the arguments given so far.

The idea is Frege's and Schönfinkel's, who used it to reduce many-place functions to one-place ones in logic;[1] the name comes from Haskell Curry, who used it throughout combinatory logic.[2]

see also

further reading

  1. [1]M. Schönfinkel, “Über die Bausteine der mathematischen Logik”, Mathematische Annalen 92 (1924).
  2. [2]H. B. Curry, R. Feys, Combinatory Logic, Vol. I, North-Holland (1958).
  3. [3]S. Mac Lane, Categories for the Working Mathematician, ch. IV, Springer (2nd ed., 1998).