如何解释这个SML类型表达式?

如何解释这个SML类型表达式?,sml,typing,Sml,Typing,这个函数被赋予了解释它的功能的指令。给出的唯一进一步信息是参数是一个二进制函数、一个值和一个列表。通过查看它,我已经知道,如果列表为nil,它将返回b值,否则它将对列表头应用二进制函数并递归。我就是不明白怎么解释这句话: (* 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) 有很多教程解释SML

这个函数被赋予了解释它的功能的指令。给出的唯一进一步信息是参数是一个二进制函数、一个值和一个列表。通过查看它,我已经知道,如果列表为nil,它将返回b值,否则它将对列表头应用二进制函数并递归。我就是不明白怎么解释这句话:

(* 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)

有很多教程解释SML的键入,但我找不到任何足够深入的内容来应用于此。有人能把它翻译成英语,让我知道它是如何工作的,以备将来参考吗?

我能够找到一个基于所谓类型推断的解决方案。我以前从未学过这个,但是

(* val bar = fn : (’a * ’b -> ’b) -> ’b -> ’a list -> ’b *)
显示函数的参数和返回类型

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

'b
引用第二个参数,一个值

“列表
指的是值列表,是函数中的第三个参数


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

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

(* val bar = fn : (’a * ’b -> ’b) -> ’b -> ’a list -> ’b *)
显示函数的参数和返回类型

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

'b
引用第二个参数,一个值

“列表
指的是值列表,是函数中的第三个参数


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

要理解这种类型的属性,首先需要理解

像这样的定义

(* val bar = fn : (’a * ’b -> ’b) -> ’b -> ’a list -> ’b *)
具有类型
int->int->int

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

例如,
val f=sum 1
分配给
f
一个函数,该函数向其输入中添加一个(换句话说,后继函数),因此,例如,
f5
的计算结果为6

在实践中,这类函数经常被使用,如
sum34
,但发生的事情并不是将两个值传递给
sum
。而是传递一个值3,返回一个函数,然后将该返回值应用于4。因此,
sum 3 4
应该被解析为
(sum 3)4
,而不是
sum(3,4)
——这将是一个类型错误

请注意,这与以下内容有根本不同

fun sum a b = a + b
它是两个变量的函数,它的类型是
int*int->int
,这不同于sum的类型
int->int->int
。后者不是前者的语法糖分,而是具有根本不同的语义

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

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

总之,一个类型为
('a*'b->'b->'b->'a list->'b
的函数,
f
是一个函数,它将任何类型为
'a*'b->'b
的函数作为输入(一个由两个变量组成的函数,其返回类型为第二个变量的类型)。
f
的返回值是
'b->'a list->'b
形式的函数。后者是一个函数,它接受
'b
类型的元素,并返回一个函数,该函数将
'a列表
发送到
'b
类型的对象

您可以这样概括:
f
是一个curried函数,它接受类型为
('a*'b->'b)
、类型为
'b
的值、类型为
'a
的值列表,并返回类型为
'b
的值。这是足够准确的,但不要误认为它等同于类型的函数

fun add (a,b) = a + b

顺便说一下,SML中最有用的两个函数,
foldl
foldr
的类型为
('a*'b->'b)->'b->'a list->'b
,因此这不仅仅是一个学术练习。能够解包此类类型描述是能够正确使用此类函数的关键。

要理解此类型的本质,首先需要理解

像这样的定义

(* val bar = fn : (’a * ’b -> ’b) -> ’b -> ’a list -> ’b *)
具有类型
int->int->int

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

例如,
val f=sum 1
分配给
f
一个函数,该函数向其输入中添加一个(换句话说,后继函数),因此,例如,
f5
的计算结果为6

在实践中,这类函数经常被使用,如
sum34
,但发生的事情并不是将两个值传递给
sum
。而是传递一个值3,返回一个函数,然后将该返回值应用于4。因此,
sum 3 4
应该被解析为
(sum 3)4
,而不是
sum(3,4)
——这将是一个类型错误

请注意,这与以下内容有根本不同

fun sum a b = a + b
它是两个变量的函数,它的类型是
int*int->int
,这不同于sum的类型
int->int->int
。后者不是前者的语法糖分,而是具有根本不同的语义

当读到这样的东西时