OCaml让多态实现

时间:2014-01-09 03:58:20

标签: ocaml type-inference parametric-polymorphism

我对let polymorphism中的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 f时,f的类型为'a -> 'a。 但对于C,在评估((f 3), (f true))时,f的类型为int -> int

为什么C f没有'a -> 'a类型?

我很难理解OCaml的实现 let polymorphism,如果有人能够简明扼要,我会非常感激 关于这个问题的描述。

1 个答案:

答案 0 :(得分:3)

您的代码不必要地混淆,因为您在B中使用相同名称f表示两个不同的内容,而在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类型的函数数量非常有限。