I made function that\'s name is maptree. And below is my code:
datatype \'a tree = LEAF of \'a | NODE of \'a tree * \'a tree;
fun maptree(f, NODE(X,
The Hindley-Milner type-inference algorithm allows you to get more general type than you expected.
When the algorithm tries to infer the type for maptree, it assumes that f: 'a -> 'b (from the fact you're using f as a function). And nothing restricts the type of f further.
If you, for example, defined the maptree function as follows (I used f twice in the LEAF case):
fun maptree(f, NODE(X, Y)) = NODE(maptree(f, X), maptree(f, Y))
| maptree(f, LEAF(X)) = LEAF(f (f X))
Then the type-inference mechanism would have to restrict the type of f to 'a -> 'a (since we feed the output of the function to its input).
The output of SML/NJ for the modified case:
val maptree = fn : ('a -> 'a) * 'a tree -> 'a tree