1

说如果我有以下功能:

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

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

4

1 回答 1

6

这是由于“let 多态性”,又名“prenex 多态性”,又名“ML 风格的多态性”。搜索这些术语将为您提供一些有关此的信息。

通俗地说,这就是类型推断的工作原理,在某些时候你需要停止泛化,并修复你的类型变量。在 ML 风格的多态中,这是在一个let级别上完成的。因此,let 绑定中的函数应该统一使用,即使用相同的参数。如果这对您来说是个问题,那么您可以使用记录、对象或(也许)该语言的一些其他功能来克服它。以下是 OCaml常见问题解答的摘录:

如何编写具有多态参数的函数?在 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
于 2015-02-06T01:20:45.330 回答