3

我对let polymorphismin感到困惑OCaml

考虑以下代码:

A: 
let f = (fun v -> v) in
((f 3), (f true))

B:
let f = (fun v -> v) in
((fun g ->
    let f = g in
    f) f)

C:
let f = (fun v -> v) in
((fun g ->
    let f = g in
    ((f 3), (f true))) f)

对于 A 和 B,没有问题。但是对于C,OCaml报错:

Error: This expression has type bool but an expression was expected of type
         int

因此,对于 A,在评估 时((f 3), (f true))f的类型是'a -> 'a,对于 B,在评估时let f = g in ff的类型是'a -> 'a。但是对于 C,在评估 时((f 3), (f true))f的类型是int -> int

为什么 Cf没有 type 'a -> 'a

我很难理解OCaml's 的实现,let polymorphism如果有人能就这个问题给出一个简明的描述,我将不胜感激。

4

1 回答 1

4

您的代码不必要地令人困惑,因为您对fB 中的两个不同事物以及 C 中的两个不同事物使用相同的名称。

在C里面你有这个功能:

fun g -> let f = g in (f 3, f true)

这又是不必要的复杂。它与以下内容相同:

fun g -> (g 3, g true)

不允许这样做的原因是它仅在g是多态函数时才有效。这需要 2 级多态性,即,它需要能够定义多态的函数参数

我不确定您要做什么,但是您可以拥有一个字段是多态函数的记录类型。然后,您可以使用此记录类型来定义类似您的函数的内容:

# type r = { f : 'a . 'a -> 'a };;
type r = { f : 'a. 'a -> 'a; }
# (fun { f = g } -> (g 3, g true)) { f = fun x -> x };;
- : int * bool = (3, true)

# let myfun { f = g } = (g 3, g true);;
val myfun : r -> int * bool = <fun>

# myfun { f = fun x -> x };;
- : int * bool = (3, true)

缺点是你需要打包和解包你的多态函数。

作为旁注,您的示例似乎不太引人注目,因为类型的功能数量'a -> 'a非常有限。

于 2014-01-09T05:13:15.527 回答