我对 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/