Types 什么是OCaml';s";地面强制;?

Types 什么是OCaml';s";地面强制;?,types,ocaml,Types,Ocaml,OCaml有时会发出警告“这种地面强制不是主要的”。我想我理解“非主体”部分(类型推断给出了至少两种可能的类型,其中任何一种都不是另一种的子类型),但我不知道“地面强制”是什么 我怀疑答案一定涉及到一些抽象类型理论,但我也非常希望有具体的例子 下面的答案来自。我从OCaml邮件列表中引用它,因为我没有找到该帖子的在线链接 [tl;dr:消息的意思是“表达式的类型未知”。 为表达式中的变量添加类型批注。“] 背景:私有类型缩写由类型别名定义 “私人”一词的定义。例如,以下 定义 type t =

OCaml有时会发出警告“这种地面强制不是主要的”。我想我理解“非主体”部分(类型推断给出了至少两种可能的类型,其中任何一种都不是另一种的子类型),但我不知道“地面强制”是什么

我怀疑答案一定涉及到一些抽象类型理论,但我也非常希望有具体的例子

下面的答案来自。我从OCaml邮件列表中引用它,因为我没有找到该帖子的在线链接

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

背景:私有类型缩写由类型别名定义 “私人”一词的定义。例如,以下 定义

type t = private int
使t成为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是什么类型的?编译器的推理算法检查 从左到右排列一对的元素,因此发生的情况如下:

  • 最初,当h的类型检查开始时,x的类型未知
  • 检查子表达式gx,将x指定为类型t,即。 g参数的类型
  • 检查强制(x:>int)并确定其正确 因为t可以强制为int
  • 但是,如果推理算法改为检查 从右到左配对我们有以下步骤顺序:

    最初,当h的类型检查开始时,x的类型未知 (2) 强制(x:>int)被检查,编译器猜测 x型。在没有其他信息的情况下,它猜测int。 (3) 检查并拒绝子表达式gx,因为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))
    

    嗯,这个信息不是很清晰,自2012年以来,有一些建议需要改变。由于打印类型的技术困难,还没有任何进展,因为它需要一个特定的格式化程序。ftr