为什么函数参数在Ocaml中不能是多态的?

时间:2015-02-06 00:46:41

标签: types polymorphism ocaml parametric-polymorphism

说我是否有以下功能:

let rejected f = (f 1, f "hi");;

它被类型检查器拒绝,我不太明白为什么类型检查拒绝它。因为f可以是多态函数(比如id),并且类型检查器应该允许它。有人可以解释一下吗?

1 个答案:

答案 0 :(得分:6)

这是因为"让多态性",又称" prenex多态性",又名" ML式多态性"。搜索此条款将为您提供有关此信息的一些信息。

用外行人的话说,这就是类型推理的工作原理,有些时候你需要停止概括,并修复你的类型变量。在ML样式的多态性中,这是在let级别上完成的。因此,应该统一使用let绑定内的函数,即具有相同的参数。如果这对您来说是个问题,那么您可以使用记录,对象或(可能)该语言的其他一些功能来克服它。以下是OCaml FAQ的摘录:

  

如何用多态参数编写函数?   在ML,一个论点   函数体内的函数不能是多态的;   因此输入以下内容:

let f (g : 'a -> 'a) x y = g x, g y 
val f : ('a -> 'a) -> 'a -> 'a -> 'a * 'a = <fun> 
  

该功能不是   我们本来希望的多态性。然而,在OCaml中它是   可以使用一阶多态性。为此,您可以使用其中之一   记录或对象;在记录的情况下,您需要声明   在函数中使用之前输入。

let f (o : <g : 'a. 'a -> 'a>) x y = o#g x, o#g y
type id = { g : 'a. 'a -> 'a; }
let f r x y = r.g x, r.g y