On p.116 of his book Harper lists the following function:
fun curry f x y = f (x, y)
At first this confused the hell out of me until I looked closely at the fact that there is a space between f and (x,y)... I wish someone would explain what that space does! Answer: it does nothing.
val curry = fn f => fn x => fn y => f(x,y) is the expansion.
The type of curry is ('a*'b->'c) -> ('a -> ('b -> 'c))
The description Harper gives for this is: Given a two-argument function, curry returns another function that, when applied to the first argument, yields a function that, when applied to the second, applies the original two-argument function to the first and second arguments, given separately.
The most obvious question for me concerns ('a -> ('b -> 'c)) --- don't you normally solve parenthesis from the inside out? Given this, why and how should I think that we take 'a first and then generate a function which expects b and c ?
Because that is the definition of how currying works. 'a -> 'b -> 'c is the same as 'a -> ('b -> 'c) by rules of associativity, just like 1 + 2 + 3 is the same as (1 + 2) + 3. -- AdamChlipala
A couple of side cases I am curious about
fun curry3 f x y z = f (x, y, z); has type val curry3 = fn : ('a * 'b * 'c -> 'd) -> 'a -> 'b -> 'c -> 'd
fun curry1 f x = f (x); has type val curry1 = fn : ('a -> 'b) -> 'a -> 'b
