我正在阅读Robert Harper的Programming in Standard ML(11.02.11版本1.2)。
解决类型推理的模糊性。罗伯特哈珀说:
重要的问题是在情况被认为含糊不清之前会考虑多少背景?经验法则是上下文被认为是最接近的封闭函数声明。
因此,以下代码将被拒绝:
let
val double = fn x => x + x
in
(double 3.0, double 4.0)
end
我认为拒绝的原因是编译器无法确定double
是int->int
还是real->real
。代码段没有提供足够的上下文来解决歧义。一些编译器默认将其设置为int->int
,这会使代码段输入错误。
我的问题是:
“最近的封闭函数声明”是什么意思?
如何使编译器通过“最近的封闭函数声明”推断函数double
的类型为real -> real
而不明确指定类型?
答案 0 :(得分:3)
我认为拒绝的原因是编译器无法确定
double
是int->int
还是real->real
。代码段没有提供足够的上下文来解决歧义。一些编译器默认将其设置为int->int
,这会使代码段输入错误。
这是大致正确的,除了实际 的代码片段提供足够的上下文来解决歧义(至少到排除int -> int
的程度);只是有些编译器在决定val double = fn x => x + x
的类型时才会考虑最小的封闭声明(在这种情况下为+
),甚至更少。这实际上是这篇文章的内容 - 编译器必须决定要考虑多少上下文,而一些编译器则比其他编译器要少。
+
默认为int * int -> int
,如果没有足够的上下文来以不同的方式解决歧义,实际上是 Definition 的附录E规定的。 / p>
- "最近的封闭函数声明"意思?
醇>
它表示包含重载运算符或常量的最小函数声明。在这种情况下,重载运算符为+
,其最近的封闭函数声明为val double = fn x => x + x
。
- 如何使编译器通过"最近的封闭函数声明"来推断函数
醇>double
的类型为real -> real
。没有明确指定类型?
如果您的意思是您不想指定整个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