Skip to content
Part IA Michaelmas Term

Shorthand and Partial Application

Curried shorthand syntax

OCaml provides a concise syntax for curried function definitions. The following two definitions are equivalent:

let prefix a b = a ^ b
(* val prefix : string -> string -> string = <fun> *)
let prefix = fun a -> fun b -> a ^ b
(* val prefix : string -> string -> string = <fun> *)

In general: let f x₁ ... xₙ = E is equivalent to:

fun x₁ -> ... -> fun xₙ -> E

Application uses the same syntax: f E₁ ... Eₙ means ((f E₁) ...) Eₙ.

Partial application

Partial application means supplying fewer arguments than a curried function expects, producing a new function with the remaining parameters.

let dub = prefix "Sir "
(* val dub : string -> string = <fun> *)

dub "Hamilton"
(* : string = "Sir Hamilton" *)

This is useful when fixing the first argument yields a function that is interesting in its own right.

Function lists and partial application

Curried functions interact naturally with lists of functions. Consider:

List.hd [dub; promote] "Hamilton"
(* : string = "Sir Hamilton" *)

Here List.hd extracts dub from the list of functions, and the resulting function is applied to "Hamilton". The type of this expression works because application associates to the left: (List.hd [dub; promote]) "Hamilton".

The idea of storing code in data structures and executing it later is fundamental to object-oriented programming.

Curried insertion sort

Passing an ordering predicate as a curried argument yields a general insertion sort:

let insort lessequal =
  let rec ins x = function
    | [] -> [x]
    | y::ys -> if lessequal x y then x :: y :: ys
               else y :: ins x ys
  in
  let rec sort = function
    | [] -> []
    | x::xs -> ins x (sort xs)
  in
  sort
(* val insort : ('a -> 'a -> bool) -> 'a list -> 'a list = <fun> *)

insort is a curried function: given an ordering predicate, it returns the sorting function itself. Usage:

insort (<=) [5; 3; 9; 8]  (* => [3; 5; 8; 9] *)
insort (>=) [5; 3; 9; 8]  (* => [9; 8; 5; 3] *)
insort (<=) ["bitten"; "on"; "a"; "bee"]  (* => alphabetical sort *)

The syntax (<=) turns the infix operator into a prefix function that can be passed as an argument. Passing (>=) yields a decreasing sort: this is valid because if ≤ is a partial ordering, then so is ≥.