OCaml 约束中隐式类型变量的范围

Scope of implicit type variables in OCaml constraints

在 Ocaml 中,您可以在约束中引入新的类型变量,这对于在类型检查器中强制执行类型标识很有用:

let f g n = (g (n:'n):'n) ;;
val f : ('n -> 'n) -> 'n -> 'n = <fun>

显然可以重复使用这些类型变量(否则这将是一个毫无意义的练习)。但是,由于它们不是由某些特殊声明引入的,我想知道它们的范围是什么?是封闭函数、let-binding 还是顶级语句?

有没有办法限制这种隐式引入的类型变量的范围?

类型约束中使用的任何类型变量的范围是封闭的 let 表达式的主体。如果一个表达式是相互递归的,则范围扩展到整个相互递归表达式集。范围不能缩小。 Let-expression 是一个打字原语。无法隐藏或覆盖类型变量。

每当引入新类型变量时,都会在当前类型上下文中查找它。如果它已经被引入,那么它就是统一的。否则,一个新的类型变量被添加到上下文中。 (以后可以用于统一)。

举例说明:

let rec f g h x y = g (x : 'a) + h (y : 'a) and e (x : 'a) = x + 1;;

这里,'a 用于在 e 中约束 x 与用于约束 xy'a 相同在函数体 f 中。由于 e 中的 xint 类型统一,统一扩展到函数 f,约束函数 gh 类型 int -> int.