解决标准 ML 中输入歧义的上下文

On context for resolving typing ambiguity in Standard ML

我正在阅读 Robert Harper 的 Programming in Standard ML(2011 年 2 月 11 日的 1.2 版)。

关于解决类型推断的二义性。罗伯特哈珀说:

The important question is how much context is considered before the situation is considered ambiguous? The rule of thumb is that context is considered up to the nearest enclosing function declaration.

因此,以下代码将被拒绝:

let
    val double = fn x => x + x
in
    (double 3.0, double 4.0)
end

我认为拒绝的原因是编译器不能决定doubleint->int还是real->real。代码片段没有提供足够的上下文来解决歧义。一些编译器默认将其设置为 int->int,这使得代码片段类型错误。

我的问题是:

  1. "nearest enclosing function declaration"是什么意思?

  2. 如何让编译器在不明确指定类型的情况下通过"nearest enclosing function declaration"推断函数double的类型是real -> real

I think the reason for the rejection is that the compiler can't decide whether double is int->int or real->real. The code snippet doesn't provide enough context to resolve the ambiguity. And some compilers set it to int->int by default which makes the code snippet ill-typed.

这大部分是正确的,除了代码片段实际上 提供了足够的上下文来解决歧义(至少到了排除 int -> int 的地步);只是有些编译器在决定 + 的类型时只会考虑最小的封闭声明(在本例中为 val double = fn x => x + x),甚至更少。这实际上就是这段话的意思——编译器必须决定要考虑多少上下文,有些编译器考虑的比其他编译器少。

+ 默认为 int * int -> int,在没有足够的上下文以不同的方式解决歧义的情况下,实际上是由 定义的附录 E 规定的 .

  1. What does "nearest enclosing function declaration" mean?

表示包含重载运算符或常量的最小函数声明。在这种情况下,重载运算符是 +,其最近的封闭函数声明是 val double = fn x => x + x.

  1. How to make the compiler infer the function double's type is real -> real by the "nearest enclosing function declaration" without specifying the type explicitly?

如果您的意思只是不想指定整个 real -> real,那么您可以这样写:

val double = fn x => x + (x : real)

如果你的意思是你根本不需要任何显式类型注释,那么我认为唯一的选择就是写一些有点 hackish 的东西,比如:

val double = fn x => x + x + 0.0

或者你可以选择:

val double = fn x => 2.0 * x