嵌套上下文中的显式多态注释

Explicitly polymorphic annotation in nested context

在下面的代码中,我不确定我是否理解为什么 _nested2 上存在类型错误。

这是否意味着只有顶层定义才能概括其推断类型以匹配显式多态签名?

let toplevel1 : 'a. 'a -> int = (fun _ -> 0)
let toplevel2 : 'a. 'a -> int = (fun (_ : 'a) -> 0)

let nest1 =
  let _nested1 : 'a. 'a -> int = (fun _ -> 0) in 0

let nest2 =
  let _nested2 : 'a. 'a -> int = (fun (_ : 'a) -> 0) in 0
(*                               ^^^^^^^^^^^^^^^^^^^
   Error: This definition has type 'a -> int which is less general than
            'a0. 'a0 -> int
*)

问题是 (l': 'a t) 注释中的 'a 类型变量存在于整个顶层定义中,因此比多态注释长。

为了说明类型变量的范围问题,请考虑

let int, id = 
  let f (x:'a) = x in
   (0:'a), f

在这里,也许令人惊讶的是,id 的类型最终变成了 int ->int 而不是 'a. 'a -> 'a,因为类型变量 'a(x:'a) 之间共享和 (0:'a).

回到最后的问题,这意味着由于转义变量 'a.

此外,只有最新版本的 OCaml(在 OCaml 4.11.0 之后)才有 toplevel2 函数:

let toplevel2 : 'a. 'a -> int = (fun (_ : 'a) -> 0)

被接受。

旧版本的 OCaml 失败

Error: This definition has type 'a -> int which is less general > than 'a0. 'a0 -> int

因为早期版本检查显式多态注解的算法没有检测到统一类型变量没有脱离顶层定义的范围。

因此,简短版本最好不要将显式多态注释与(统一)类型变量混合使用。