关于解决标准ML中输入歧义的背景

时间:2015-01-20 01:01:19

标签: types sml type-inference ml

我正在阅读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

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

我的问题是:

  1. “最近的封闭函数声明”是什么意思?

  2. 如何使编译器通过“最近的封闭函数声明”推断函数double的类型为real -> real而不明确指定类型?

1 个答案:

答案 0 :(得分:3)

  

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

这是大致正确的,除了实际 的代码片段提供足够的上下文来解决歧义(至少到排除int -> int的程度);只是有些编译器在决定val double = fn x => x + x的类型时才会考虑最小的封闭声明(在这种情况下为+),甚至更少。这实际上是这篇文章的内容 - 编译器必须决定要考虑多少上下文,而一些编译器则比其他编译器要少。

+默认为int * int -> int,如果没有足够的上下文来以不同的方式解决歧义,实际上是 Definition 的附录E规定的。 / p>

  
      
  1. "最近的封闭函数声明"意思?
  2.   

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

  
      
  1. 如何使编译器通过"最近的封闭函数声明"来推断函数double的类型为real -> real。没有明确指定类型?
  2.   

如果您的意思是您不想指定整个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