如何解释此SML类型表达式?

时间:2016-12-06 03:30:12

标签: sml typing

(* val bar = fn : (’a * ’b -> ’b) -> ’b -> ’a list -> ’b *)
fun bar f b nil = b
| bar f b (h::t) = f (h, bar f b t)

这个功能是给我们的,说明了解它的功能。给出的唯一进一步信息是参数是二元函数,值和列表。通过查看,我已经知道如果列表为nil,则返回b值,否则它将二进制函数应用于列表头并进行递归。我只是不明白如何解释这一行:

(* val bar = fn : (’a * ’b -> ’b) -> ’b -> ’a list -> ’b *)

有许多教程解释SML的输入,但我找不到足够深入的东西来应用于此。任何人都可以把它翻译成英文,所以我知道它的工作原理以供将来参考吗?

2 个答案:

答案 0 :(得分:3)

要了解此类型的sgnature,您需要先了解currying

这样的定义
fun sum a b = a + b

的类型为int -> int -> int

它是一个变量(整数)的函数,其中返回值本身就是一个函数,它将整数发送给整数。

例如,val f = sum 1f分配一个函数,该函数在其输入中添加一个函数(换句话说,后继函数),以便例如f 5求值为6。 / p>

在实践中,这些功能通常像sum 3 4一样使用,但在那里发生的事情并非将2个值传递给sum。而是传递一个值3,它返回一个函数,然后将此返回值应用于4.因此,sum 3 4应该被解析为(sum 3) 4而不是sum (3,4) - 将是一个类型错误。

请注意,这与

等根本不同
fun add (a,b) = a + b

其中两个变量的函数,它具有类型int * int -> int,它与总和的int -> int -> int类型不同。后者不是前者的语法糖,而是具有根本不同的语义。

在阅读诸如int -> int -> int之类的内容时,您应将其视为右关联。换句话说,它与int -> (int -> int)相同。

('a * 'b -> 'b) -> 'b -> 'a list -> 'b发生的另一件事是使用类型变量 'a, 'b。这意味着您尝试解析的类型是高阶多态函数。它'a'b可以代表任何类型。

将所有这些放在一起,类型f的函数('a * 'b -> 'b) -> 'b -> 'a list -> 'b是一个函数,它将任何类型为'a * 'b -> 'b形式的函数作为输入(两个变量的函数)其返回类型是第二个变量的类型)。 f的返回值是'b -> 'a list -> 'b形式的函数。后者是一个函数,它接受'b类型的元素并返回一个函数,该函数将'a lists发送到'b类型的对象

您可以通过说f curried 函数来概括它,该函数采用类型为('a * 'b -> 'b)的函数,类型为'b的值,列表类型为'a的值,并返回类型'b的值。这是足够准确的,但不要认为它等同于类型

的函数
('a * 'b -> 'b) * 'b * 'a list -> 'b

顺便说一下,SML中最有用的两个函数foldlfoldr都有('a * 'b -> 'b) -> 'b -> 'a list -> 'b类型,所以这不仅仅是一个学术练习。能够打开这种类型的描述是能够正确使用这些功能的关键。

答案 1 :(得分:1)

我能够根据所谓的类型推理找到解决方案。我之前从未学过这个,但是

(* val bar = fn : (’a * ’b -> ’b) -> ’b -> ’a list -> ’b *)

显示函数的参数和返回类型。

(’a * ’b -> ’b)指的是第一个参数函数。它本身需要2个参数('b'a)并返回1个值'b

'b引用第二个参数,即值。

'a list是指值列表,是函数中的第三个参数。

最后,最后一个'b是返回值。