什么是OCaml"地面强制"?

时间:2015-05-28 15:59:58

标签: types ocaml

OCaml有时会发出警告"这种地面胁迫不是主要的"。我想我理解"不是校长" part(类型推断给出了至少两种可能的类型,两者都不是另一种的子类型),但我不知道"地面强制"是

我怀疑答案必须涉及一些抽象类型理论,但我也非常感谢具体的例子。

1 个答案:

答案 0 :(得分:7)

  

以下答案来自Jeremy Yallop。我从OCaml邮件列表中引用它,因为我找不到发布的在线链接。

[tl; dr:消息的意思是“表达式的类型未知。 为表达式中的变量添加类型注释。“]

背景:私有类型缩写由类型别名定义 用'私人'一词定义。例如,以下内容 定义

type t = private int

为int提供了一种半别名:你可以从类型t转换为 int,但是你不能从int转换为t。执行强制 使用':>'运算符,所以你可以写这样的东西

let f (x : t) = (x :>  int)

从私有类型t转换为缩写类型int。

现在,为了检查以下强制是否有效

(x :> int)

编译器需要知道x的类型。可能有几个 候选人:例如,上面的私人类型缩写 范围,如果x具有类型t,则强制有效,但是无操作强制 也是允许的,因此int是另一种合理的可能性。怎么能 编译器在这些替代方案之间进行选择以找到x的类型? 在f的定义中,选择很容易:x是一个函数 带有注释的参数,因此编译器只使用它 注解。这是一个稍微棘手的案例:

let g (y : t) = ()

let h x = (g x, (x :> int))

这里的x是什么类型的?编译器的推理算法检查 从左到右的一对元素,所以这是发生的事情:

  1. 最初,当h的类型检查开始时,x的类型未知
  2. 检查子表达式g x,为x分配类型t,即 g的论证类型
  3. 检查强制(x:> int),并确定其是正确的 因为t可以被强制转换为int。
  4. 但是,如果推理算法检查了a的元素 从右到左对,我们有以下一系列步骤:

    最初,当h的类型检查开始时,x的类型是未知的   (2)检查强制(x:> int),编译器猜测 x的类型。在没有其他信息的情况下,它会猜测。   (3)检查并拒绝子表达式g x,因为x具有 输入int,而不是t。

    确实,如果我们交换对的元素来模拟这个 第二种行为

    let h2 x = ((x :> int), g x)
    

    然后强制被拒绝:

    let h x = ((x :> int), g x);;
                             ^
    Error: This expression has type int but an expression was expected of type t
    

    因为不依赖于特定订单的程序更好 由推理算法使用,编译器发出警告。您 可以通过注释x:

    的绑定来解决警告
    let h (x : t) = (g x, (x :> int))