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

Types 解决标准ML中键入歧义的上下文,types,sml,type-inference,ml,Types,Sml,Type Inference,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。代码段没有提供足够的上下文来解决歧义。

我正在读罗伯特·哈珀的(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
    ,而不显式指定类型

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

    这基本上是正确的,除了代码片段确实提供了足够的上下文来解决歧义(至少可以排除
    int->int
    );只是一些编译器只考虑最小的包围声明(在这种情况下是代码> Value2= fn x= > x+x),或者甚至更少,在决定<代码> +<代码>的类型。这实际上是这篇文章的内容-编译器必须决定要考虑多少上下文,一些编译器考虑的比其他的要少。 在没有足够的上下文以不同的方式解决歧义的情况下,
    +
    默认为
    int*int->int
    ,这实际上是定义的附录E规定的

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

  • 如何让编译器通过“最近的封闭函数声明”推断函数
    double
    的类型为
    real->real
    ,而不显式指定类型
  • 如果您的意思只是不想指定整个
    real->real
    ,那么您可以编写:

    val double = fn x => x + (x : real)
    
    如果您的意思是根本不需要任何显式类型注释,那么我认为唯一的选择是编写一些有点粗糙的东西,例如:

    val double = fn x => x + x + 0.0
    
    或者你可以选择:

    val double = fn x => 2.0 * x
    
    谢谢但是在这种情况下,“最近的封闭函数声明”不是指整个
    valdouble=fnx=>x+x
    函数声明吗?如果它只表示默认值为
    int->int
    +
    ,那么
    val double:real->real=fn x=>x+x
    不会键入错误吗?@Ben:By“重载运算符或常量(在本例中为
    +
    )”我的意思是在本例中
    +
    是重载运算符或常量,在这种情况下,
    +
    不是最接近的封闭函数声明。我现在重新措辞,以消除这种歧义。