Why is the type inferred for my ML function different than I expect?

久未见 提交于 2019-12-02 09:37:54

问题


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, Y)) = NODE(maptree(f, X), maptree(f, Y))
| maptree(f, LEAF(X)) = LEAF(f X);

I expected maptree to have the type

 ('a -> 'a) -> 'a tree -> 'a tree

but the type inferred by the compiler is

 ('a -> 'b) * 'a tree -> 'b tree

Why is this happening?


回答1:


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


来源:https://stackoverflow.com/questions/36998218/why-is-the-type-inferred-for-my-ml-function-different-than-i-expect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!