OCaml的let多态实现

标签 ocaml type-inference parametric-polymorphism

我对 OCaml 中的 let polymorphism 感到困惑。

考虑以下代码:

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,如果有人能给出一个简洁的代码,我将不胜感激 关于问题的描述。

最佳答案

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

在 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 类型的函数数量非常有限。

关于OCaml的let多态实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21011349/

相关文章:

function - OCaml:没有定义值的柯里化(Currying)

c++ - C++ 11 auto关键字多少太多了?

haskell - rank-3(或更高)多态性的用例?

generics - 如何限制运算符实现的右侧参数的类型?

performance - Coyoneda 类型的 NFData 实例

recursion - 变体、递归函数和类型推断

module - OCaml 模块 : bringing (interconnected) types from different modules into a new module

functional-programming - 重载函数的 Hindley-Milner 类型推断

type-inference - D 中的函数和委托(delegate)文字

OCamlLex 不区分大小写