了解函数类型签名



我在理解OCaml中高阶函数的函数类型签名时遇到问题。

fun f -> f 3
(int -> a) -> a

我处理这个问题的方式是f 3部分将int作为输入并返回函数f定义的类型,该类型表示为a。所以真的,fun f是一种(int->a)型。但是,(int -> a) ->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的来源。

最新更新