Could someone please explain to me what is going on in these three bindings? What is the significance of the parens? What is the meaning of g and why does it have to be a g as an argument in the anonymous function? And overall what is actually happening in all of this... Thank you!
val a = fn g => (fn x => fn y => x) (g 0) (g 7);
val b = fn g => (fn x => fn y => x) (g 0) (g "happy");
val c = fn g => (fn x => fn y => x) (g 0) (g (g 7));
The function
(fn x => fn y => x)
is the constant function. It takes two arguments (x
andy
) and always returns the first argument (i.e.x
).This function is applied to two arguments in all three functions
a
,b
andc
:a
the constant function is applied to(g 0)
and(g 7)
.b
the constant function is applied to(g 0)
and(g "happy")
.c
the constant function is applied to(g 0)
and(g (g 7))
.In all three cases, the result is
(g 0)
because the second argument is discarded. Therefore, all the three functions can be simplified to:Actually, the second function (i.e.
b
) raises a type error becauseg
is first applied to anint
and later applied to astring
.Although the functions
a
andc
have the same result yet they do not have the same type:a
is(int -> 'a) -> 'a
because we don't know the return type of the functiong
. Hence, it is a polymorphic function and it's more general thanc
.c
is(int -> int) -> int
becauseg
is applied to its own result (i.e.g
is applied to(g 7)
). Hence, its return type must be the same as its argument type (i.e.int
).Therefore,
a
is more general thanc
and every instance ofc
can be safely replaced witha
but not vice versa.