I'm making my way through Ullman's Elements of ML Programming. He introduces a datatype for a BST in ch. 6 as follows:
datatype 'label btree =
Empty |
Node of 'label * 'label btree * 'label btree;
Then he defines a lookup function to tell whether a node with a given label exists within the BST:
fun lookup lt Empty x = false
| lookup lt (Node(y, left, right)) x =
if lt(x, y) then lookup lt left x
else if lt(y, x) then lookup lt right x
else true;
ML tells us that the function is of type:
val lookup = fn : ('a * 'a -> bool) -> 'a btree -> 'a -> bool
1) I'm having trouble parsing what the above means. I know "->" associates from the right, but I'm having trouble sorting out how to do this. How would you know how to do this just by looking at the above?
val lookup = fn : ('a * 'a -> bool) -> ('a btree) -> ('a) -> (bool)
2) I'm confused though, because I thought curried functions create a chain of functions that return another function with each subsequent argument. But based on the types ML is giving me above, it looks like it's not curried. Any idea what's going on here?
Thanks for the help, bclayman
The type val lookup = fn : ('a * 'a -> bool) -> 'a btree -> 'a -> bool
tells us that it takes an argument of type ('a * 'a -> bool)
and returns a function of type 'a btree -> 'a -> bool
. This function then takes in something of type 'a tree
and returns a function of type 'a -> bool
, which then takes in an argument of type 'a
and returns a bool
. So yes, the lookup
function is curried. The first parameter (which is a function as well), however, is not curried as it takes in two arguments, wrapped up in a pair. In general, you can take a curried function (i.e. one that takes an argument and returns a function) and transform it into an uncurried function in the following way:
Let's say you have the following function
fun f e1 e2 e3 ... = e
of type
'a -> 'b -> 'c -> ... -> 'res
We can uncurry this function by wrapping all the inputs in a tuple, such as
fun f(e1, e2, e3, ...) = e
Which will then have the type
'a * 'b * 'c * ... -> 'res