我来自命令式背景

我读 这里 关于 cons

(cons x l):

给定一个LISP对象X和一个列表L,评估(cons x l)创建一个包含X的列表,其后是L。

当我故意不使用列表作为第二个参数时,即

(cons 'a 'a) 我期待一个错误,但哇!我有 (A . A).

我错过了什么,什么是 (A . A)?

有帮助吗?

解决方案

Cons 构建一个“ Cons Cell”。首先,这与列表无关。一个cons单元是两个值。缺点单元以“虚线对”为书面形式表示,例如 (A . B), ,有两个值 'A'B.

缺席单元中的两个地方称为“汽车”和“ CDR”。您可以将这种缺陷单元视为一个二选块:

  car   cdr
+-----+-----+
|  A  |  B  |
+-----+-----+

在LISP中,值也可以是对其他事物的引用,例如另一个缺点细胞:

+-----+-----+       +-----+-----+
|  A  |   --------> |  B  |  C  |
+-----+-----+       +-----+-----+

这将以“虚线对”形式表示为 (A . (B . C)). 。您可以这样继续:

+-----+-----+       +-----+-----+       +-----+-----+
|  A  |   --------> |  B  |   --------> |  C  |  D  |
+-----+-----+       +-----+-----+       +-----+-----+

这是 (A . (B . (C . D))). 。如您所见,在这样的结构中,这些值始终在 car 缺席细胞和 cdr 指向其余结构。一个例外是最后一个值,这是最后一个值 cdr. 。但是,我们不需要这个例外:有一个特殊的价值 NIL 在LISP中,表示“无”。通过放置 NIL 进入最后一个 cdr, ,您有方便的前哨价值,并且 全部 您的价值在 carS:

+-----+-----+       +-----+-----+       +-----+-----+       +-----+-----+
|  A  |   --------> |  B  |   --------> |  C  |   --------> |  D  | NIL |
+-----+-----+       +-----+-----+       +-----+-----+       +-----+-----+

这就是LISP构建列表的方式。自从 (A . (B . (C . (D . NIL)))) 有点笨拙,也可以简单地表示 (A B C D). NIL 也称为空列表 ();这些是同一件事的交换符号。

现在您可以看到为什么 (cons x list) 返回另一个列表。 Cons 只需用 x 在里面 car 并提及 list 在里面 cdr:

+-----+-----+
|  X  |   --------> list
+-----+-----+

而如果 list(A B), ,它的作用为:

+-----+-----+       +-----+-----+       +-----+-----+
|  X  |   --------> |  A  |   --------> |  B  | NIL |
+-----+-----+       +-----+-----+       +-----+-----+

所以, (cons x '(a b)) 评估 (x a b).

列表只是缺点单元的一种非常普遍的用途。实际上,实际上,您还可以从缺点单元格,圆形列表或任何有向图的图形中构造任意树。

其他提示

'a 是一个原子, (A . A) 是一个堕落的列表称为 缺点细胞 或“虚线对”。由于您没有通过列表进行参数 L(cons x L) 你把一个牢房拿回来。

(con x l)

给定的X和L,缺点将带有X作为该单元的汽车和L作为该单元的CDR返回一个新的缺点细胞。

列表是缺席细胞的链接链。

CL-USER 141 > (sdraw '(a b c))

[*|*]--->[*|*]--->[*|*]---> NIL
  |        |        |
  v        v        v
  A        B        C

CL-USER 142 > (sdraw (cons 'foo '(a b c)))

[*|*]--->[*|*]--->[*|*]--->[*|*]---> NIL
  |        |        |        |
  v        v        v        v
 FOO       A        B        C

如果Cons获得两个符号作为参数,则看起来像这样:

CL-USER 143 > (sdraw (cons 'foo 'bar))

[*|*]---> BAR
  |
  v
 FOO
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top