说我是否有以下功能:
let rejected f = (f 1, f "hi");;
它被类型检查器拒绝,我不太明白为什么类型检查拒绝它。因为f可以是多态函数(比如id
),并且类型检查器应该允许它。有人可以解释一下吗?
答案 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