SML:运算符```::``` 是不是正确结合并且应该用作```<类型a的值>::<带有类型a的元素的列表>```?

问题描述

好的,所以我对 cons 运算符有点困惑::: 我知道这是可以接受的:

   > [2]
   or this
   2::[2,4]
   > [2,2,4]
and i kNow this is forbbiden
   [2]::[3]
it won't work.
but I recently found out that :
  [2]::[3]::nil
will work :
 > [[2],[3]]
or 
 [2]::[] will do as well.
 >[[2]]

我的问题是为什么? 我在想,也许这是一个规则,如果我有一个类型为 a 的列表,那么我只能创建一个类型为 a 的新列表。 所以例如当我有

[2] :: [3]
我的列表具有 int 类型的元素,但我要求将一个非初始化值 [3] ??
连接到一个 int 列表中 但是当我有 [2]::[3]::[] 时,空列表 [] 可能是任何类型的空列表,所以在这里我需要它是一个空列表,包含像 [3] 这样的元素,所以它将元素 [3] 添加到 nil 中,然后将元素 [2] 添加到 nil 中,依此类推...
所以是这个原因吗?还有别的吗?

解决方法

在 SML 中,列表定义如下:

datatype 'a list = nil | :: of 'a * 'a list

特别是,::'a * 'a list -> 'a list 类型的中缀构造函数。

语法 [1,2,3]1 :: 2 :: 3 :: nil 的糖。

您不仅需要构造包含 int 的列表(即 where 'a = int);例如,您可以拥有包含 int list 的列表,即一个 int list list。这就是您创建的内容:

[2] :: [3] :: nil
(* can be sugared as *)
[[2],[3]]

(同样,您可以选择 'a = string 并创建列表 "hello" :: "world" :: nil,即 ["hello","world"]。)


如果要附加两个列表,可以使用中缀 @,其类型为 'a list * 'a list -> 'a list。例如:

[1,2] @ [3]
(* evaluates to [1,3] *)