我可以使用什么类型注释来允许对函数的不同调用来采用不同的多态类型

What type annations can I use to allow different calls to a function to assume different polymoprhic types

这个问题与我问的另一个问题有关 here

但是这个问题更侧重于我在尝试理解 (type a): : type a..

等不同类型注释时编写的这段简单代码
let f = fun id x -> 
    let i = id 4 in
    let f = id 4.0 in
       (Int.to_float i) +. f;;

此代码不进行类型检查。我知道这是因为来自 let i = id 4 的检查器 'infers' id : int -> ... 但这与下一行的推断 id : float -> ... 冲突。

如果我们能以某种方式告诉类型系统函数 id 是类型 a -> a 并且这种类型允许呼叫站点之间有所不同。 (即我们可以在每次调用 id 时选择不同的 'a)。

我收集到像 type a.(type a) : 这样的注释正是为了让我以某种方式告诉类型检查器。

这是我尝试过的方法之一。我把id的'binding occurrence'注解为使用type a.来尝试使它成为'explicitly polymorphic'。但是语法不允许我在那里实际使用 type a. ... 作为类型注释。

let f = fun (id : type a.a -> a) x -> begin 
               (* ^^^^ syntax error: type expected *) 
         let i = id 4 in
         let f = id 4.0 in
         (Int.to_float i) +. f
end;;

有点confusing/ironic那个错误。它指向单词 'type' 并表示预期的是 type。我收集到的错误意味着它需要 'a type' 而不是关键字 type。但是我认为(我猜错了) type a. ... 实际上会被认为是有效的 'type'.

所以,最后的问题是 一些 方法来注释我的代码段并进行类型检查?还是不可能?

这里的根本问题是这需要 higher-rank 多态性,而 OCaml 不隐式支持它。解决方法是通过将函数包装在记录或对象中使其显式化,这允许在字段或方法级别上进行通用量化。

type f = { f: 'a. 'a -> 'a }

let f = fun id ->
   let i = id.f 4 in
   let f = id.f 4.0 in
   float_of_int i +. f

请参阅 OCaml 手册中有关 Polymorphism and its limitations 的部分以获得更详细的解释。