为什么为我的 ML 函数推断的类型与我预期的不同?
Why is the type inferred for my ML function different than I expect?
我创建了名为 maptree
的函数。下面是我的代码:
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);
我希望 maptree 具有类型
('a -> 'a) -> 'a tree -> 'a tree
但是编译器推断的类型是
('a -> 'b) * 'a tree -> 'b tree
为什么会这样?
Hindley-Milner 类型推断算法允许您获得比预期更通用的类型。
当算法尝试推断 maptree
的类型时,它假定 f: 'a -> 'b
(根据您将 f
用作函数的事实)。并且没有进一步限制 f
的类型。
例如,如果您按如下方式定义 maptree
函数(我在 LEAF
的情况下使用了两次 f
):
fun maptree(f, NODE(X, Y)) = NODE(maptree(f, X), maptree(f, Y))
| maptree(f, LEAF(X)) = LEAF(f (f X))
然后类型推断机制必须将 f
的类型限制为 'a -> 'a
(因为我们将函数的输出提供给它的输入)。
修改后的 SML/NJ 的输出:
val maptree = fn : ('a -> 'a) * 'a tree -> 'a tree
我创建了名为 maptree
的函数。下面是我的代码:
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);
我希望 maptree 具有类型
('a -> 'a) -> 'a tree -> 'a tree
但是编译器推断的类型是
('a -> 'b) * 'a tree -> 'b tree
为什么会这样?
Hindley-Milner 类型推断算法允许您获得比预期更通用的类型。
当算法尝试推断 maptree
的类型时,它假定 f: 'a -> 'b
(根据您将 f
用作函数的事实)。并且没有进一步限制 f
的类型。
例如,如果您按如下方式定义 maptree
函数(我在 LEAF
的情况下使用了两次 f
):
fun maptree(f, NODE(X, Y)) = NODE(maptree(f, X), maptree(f, Y))
| maptree(f, LEAF(X)) = LEAF(f (f X))
然后类型推断机制必须将 f
的类型限制为 'a -> 'a
(因为我们将函数的输出提供给它的输入)。
修改后的 SML/NJ 的输出:
val maptree = fn : ('a -> 'a) * 'a tree -> 'a tree