我无法理解OCaml中高阶函数的函数类型签名。
fun f -> f 3
(int -> a) -> a
我处理此问题的方式是f 3
部分将int
作为输入并返回由函数f
定义的类型,该类型被表示为a
。因此,实际上fun f
是类型(int->a)
。但是最后一个来自a
(int -> a) ->
的 a
在哪里?
答案 0 :(得分:5)
您的第一个示例是:
fun f -> f 3
我认为您可能会感到困惑的是,您正在将其视为名为f
的函数的定义。不是这种情况。这是代表函数的匿名值,也称为lambda。 f
代表此匿名函数的参数。
为使情况更清楚,我们将函数命名为g
。换句话说,假设我们像这样定义g
:
let g = fun f -> f 3
好的,因此g
是一个使用一个参数f
的函数。这个f
参数显然是一个函数,因为我们看到它被应用于3。(即,我们看到它以3作为参数被调用。)g
返回什么?它会返回f
调用时返回的内容,对吧?
由于g
是一个函数,因此其类型必须为这种形式:
d -> c
也就是说,它接受d
类型的东西,并返回c
类型的东西。根据上述推理,我们知道d
是一个函数类型,并且我们还知道该函数的返回类型也是g
的返回类型。因此,如果d
是b -> a
(更详细而言),则g
的完整类型如下:
(b -> a) -> a
但是我们也知道函数参数f
带有一个int参数,因为我们看到它被应用于3。所以类型b
必须是int
。这为g
的类型提供了以下内容:
(int -> a) -> a
我希望这可以使事情变得更清楚。
答案 1 :(得分:0)
我们可以这样注释匿名函数:
fun (f : int -> 'a) -> (f 3 : 'a)
也就是说,它是一个从f : int -> 'a
到'a
的函数,因此这就是您最后一个'a
的来源。