我想知道SML中空列表的确切类型是什么(我使用的是PolyML)?
当我在解释器中输入[]
时,我会离开:
val it = []: 'a list
这是我所期待的。但是,如果我输入说:
fun f a = if a = 0 then [] else [[]];
然后我得到:
val f = fn: int -> 'a list list
这似乎意味着[]
也具有'a list list
类型。这究竟是如何工作的?
答案 0 :(得分:4)
在ML术语中,值具有类型方案,而不是类型。类型方案是类型的集合。它是带有通配符的类型,通配符可以替换为任何类型。按类型替换通配符称为实例化类型方案。
在'a list
中,'a
是一个类型变量,即通配符。空列表[]
可以用于任何类型为'a list
类型的实例。也就是说,对于任何类型T
,空列表都具有类型T list
。例如,空列表的类型为int list
,类型为bool list
,类型为(int * int * int) list
,类型为int list list
,依此类推。所有这些类型都是类型方案'a list
的实例。
当变量多次出现时,必须一致地替换它。例如fn x => x
(标识函数)具有类型方案'a -> 'a
;它的类型为int -> int
,类型为bool -> bool
,但类型为int -> bool
。方案'a -> 'b
类型的值也将具有类型int -> bool
。
值可以有多种类型 - 这是编程语言中的常见现象。核心ML语言的一个属性是,良好类型的值的类型集恰好是类型方案的实例集。此属性称为公约:ML的类型系统是主体。 ML的具体实施倾向于对公国有例外;例如,由于运算符重载,SML有一个例外(fn x => x + x
有两种类型int -> int
和float -> float
,重载解析规则导致编译器决定int -> int
如果上下文没有强加float
)。
其主要类型方案包含至少一个变量的值被称为多态。其主体类型方案不包含变量的值被称为单态。
通配符可以由类型方案替换。这产生另一种类型方案,其是原始集合的子集,即类型方案是原始的较小类型方案(细化)。例如,值[[]]
具有类型方案'a list list
:对于任何类型T list list
,其类型为T
。 [[]]
的类型为int list list
,类型为bool list list
,类型为(int * int * int) list list
等。
在关于ML的文献中,“类型”通常与“类型方案”互换使用,因此通常会说“空列表具有类型'a list
”。在关于类型系统的文献中,“类型”通常表示ML术语称为“类型方案”,而诸如“地面类型”的其他术语用于没有变量的类型。