我无法理解OCaml中高阶函数的函数类型签名。
fun f -> f 3
(int -> a) -> a
我处理这个的方式是f 3
部分采用int
作为输入并返回由函数f
定义的类型,表示为a
。所以真的,fun f
是一种(int->a)
。但那么a
(int -> a) ->
的最后一个a
来自哪里?
你的第一个例子是这样的:
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
我希望这有助于使事情更加清晰。
我们可以注释匿名函数:
fun (f : int -> 'a) -> (f 3 : 'a)
即,这是从f : int -> 'a
到'a
的功能,所以这是你的最后一个'a
来自哪里。