SML-NJ列表等于Nil vs Null List

时间:2014-04-10 02:06:02

标签: list null sml smlnj

我对新泽西州SML解释清单的方式有疑问:

假设我有一个函数f(x : 'a, n : int) : 'a listf会返回n xf(2,5) = [2,2,2,2,2]个副本的列表,例如f(9,0) = []f(9,0) = nil

然后我进入REPL,然后检查list = nil,它返回true。由此,我假设您可以使用list来检查null list是否为空列表。我在一个函数中使用它,它不会运行。我最后得知类型定义不同:

  

sml:121.2-123.10错误:运算符和操作数不同意[需要相等类型]     运营商域名:'' Z *'' Z
    操作数:'列表*' Y列表
    在表达中:
      xs = nil

(其中xs是我的清单)。然后我了解到检查列表是否为空列表的方法是使用nil。为什么会这样? (case xs = of nil发生了什么?有人可以向我解释这种行为吗?

我还注意到显然null xs与检查{{1}}相同。这是否意味着nil是一种类型?

1 个答案:

答案 0 :(得分:6)

这是与多态性相关的错误。默认情况下,在评估空列表时,它的类型为'a list。这意味着列表可以包含任何类型的元素。如果您尝试评估1::[],则不会因此而导致类型错误。这称为多态,它是一个允许函数接受任何类型参数的功能。这在null这样的函数中非常有用,因为在这种情况下你不关心列表的内容,你只关心它的长度(实际上,你只关心它的长度)空或不)。 但是,您也可以使用不同类型的空列表。您可以使函数返回一个空的int列表。事实上,你正在这样做。

这是您的功能的简单实现的结果:

- fun f(x : 'a, n : int) : 'a list =
    case n of
        0 => []
      | _ => x::f(x, n-1);
val f = fn : 'a * int -> 'a list
- f(4,5);
val it = [4,4,4,4,4] : int list
- f(4,0);
val it = [] : int list

如您所见,即使第二个参数为0,您的函数也会返回一个int列表。您应该能够将其直接与类型'a list的列表进行比较。

- it = [];
val it = true : bool

但是,如果您尝试比较两个具有不同类型但不是'a list类型的空列表,则应该收到错误消息。你可以在下面看到它的一个例子:

- [];
val it = [] : 'a list
- val list1 : int list = [];
val list1 = [] : int list
- val list2 : char list = [];
val list2 = [] : char list
- list1 = [];
val it = true : bool
- list2 = [];
val it = true : bool
- list1 = list2;
stdIn:6.1-6.14 Error: operator and operand don't agree [tycon mismatch]
  operator domain: int list * int list
  operand:         int list * char list
  in expression:
    list1 = list2

此外,case xs of nil是一种检查列表是否为空的方法,但这是因为nil(这只是一种编写[]的方式)具有类型{{1 }} 默认情况下。 (请注意,case表达式不会直接返回布尔值。)因此,'a list不是类型,但nil是一种多态类型,可以与任何类型的列表进行比较,但是如果您的空列表没有多态类型,您将收到类型错误,我认为您的情况会发生什么。