为什么使用cons创建一对两个列表会产生一个列表和两个元素?

时间:2010-06-11 11:59:36

标签: lisp scheme racket

我开始学习Scheme,主要是为了好玩,因为我之前从未使用过函数式语言。我之所以选择Scheme,是因为我想长时间阅读SICP

无论如何,我目前正在学习列表,在此之前我了解了cons,car和cdr。还有一个例子可以创建一个带有缺点的列表列表,如下所示:

(cons (list 1 2) (list 3 4))

结果列表是((1 2)3 4),这对我没有意义,我希望((1 2)(3 4))成为结果(列表由两个列表组成) )。为什么它表现得那样?我意识到,如果我要使用汽车,我会得到(1 2),而cdr我会得到(3 4)因为cdr总是返回“其余的”,但我不明白为什么列表没有制作两个名单?

4 个答案:

答案 0 :(得分:9)

你得到一个列表,(1 2)作为第一个元素(汽车),(3 4)作为其余部分(cdr),因为cons的第一个参数是列表的第一个元素,第二个元素是参数是包含剩余项目的列表。

这非常类似于列表的结构:(正确)列表的每个节点都包含一个元素和一个包含所有其他元素的列表。 cons创建了一个这样的节点。

如果cons的第二个参数将成为列表的第二个元素,那么如何创建一个包含三个参数的列表?您必须在此时设置cons变量,它只是list的另一个名称。

如果要创建列表列表,请使用(list (list 1 2) (list 3 4))

答案 1 :(得分:3)

(list (list 1 2)
      (list 3 4))

相同
(cons (list 1 2)
      (cons (list 3 4)
            '()))

结果是

((1 2) (3 4))

也可以写成

((1 . (2 . ()))
 . 
 ((3 . (4 . ()))
  .
  ()))

答案 2 :(得分:1)

list A:  [  |      ]
          1   [ | ]
               2 /

list B:  [  |      ]
          3   [ | ]
               4 /

======================

(cons A B)

[           |           ]
 [  |     ]   [  |     ]
  1  [ | ]     3  [ | ]
      2 /          4 / 

内部结构的图形表示可以帮助我们可视化问题。

这将有助于更多:

[           |           ]
     X        [  |     ]
               3  [ | ]
                   4 / 

你看到了这种模式吗?以上是列表(X 3 4)。这就是(cons A B)仅将car部分作为单独列表而不是cdr绘制的原因。

答案 3 :(得分:0)

因为cons-cell 是两个元素的列表,所以这两个元素经常混淆。如果(a . b)是一个cons单元格,则(a . (b . ()))是两个元素的列表。任何列表都安全,空列表具体是一个cons单元,其car字段包含第一个元素,其cdr字段包含包含其余元素的列表。因此,列表只是一个二叉树,其最右边的叶子是特殊常量()nil,具体取决于您的方言。

这就是为什么(cons 0 '(1 2 3))评估为(0 1 2 3)而非(0 (1 2 3))的原因我们创建了一个车辆为0且其cdr为(1 2 3)的cons小区,因此列表(0 1 2 3)