Making pairs from two arguments ------------------------------- Assume we have the following functions: - val first = fn x => fn y => x; (* first = Lx.Ly.x *) val first = fn : 'a -> 'b -> 'a - val second = fn x => fn y => y; (* second = Lx.Ly.y *) val second = fn : 'a -> 'b -> 'b - ((first 1) 2); val it = 1 : int - ((second 1) 2); val it = 2 : int - val I' = (second second); (* A new definition of the identity function I. In fact we can replace argument with ANYTHING *) val I' = fn : 'a -> 'a - I' 5; val it = 5 : int - I' I'; val it = fn : 'a -> 'a - val pair = fn x => fn y => fn f => ((f x) y); val pair = fn : 'a -> 'b -> ('a -> 'b -> 'c) -> 'c - (* pair = Lx.Ly.Lf.((f x) y) *) - val p = ((pair 1) 2); Lets look at this: ((pair 1) 2) => ((Lx.Ly.Lf.((f x) y) 1) 2) => (Ly.Lf.((f 1) y) 2) => Lf.((f 1) 2) That is ((pair x) y) reduces to a lambda expression which applies the argument function f to x, delivering a new function which is then applied to y. Therefore (the pair) p is a fuction as follows: val p = fn : (int -> int -> 'a) -> 'a We now may apply p to a function (!! sounds ass-backwards !!) that will deliver either the first or second element of p: - (p first); val it = 1 : int That is: (Lf.((f 1) 2) first) => ((first 1) 2) => ((Lx.Ly.x 1) 2) => (Ly.1 2) => 1 - (p second); val it = 2 : int That is: (Lf.((f 1) 2) second) => ((second 1) 2) => ((Lx.Ly.y 1) 2) => (Ly.y 2) => 2