我在Scheme(使用DrRacket)中获得了一项任务,要求我使用cons从组件1,2,3和()
创建列表((1 2)3)我设法得到((1 2)。3)使用:
(cons (cons '1 (cons '2 '())) '3)
然而,这是一回事吗?
答案 0 :(得分:4)
注意:这是从my answer到Recursive range in Lisp adds a period?的蚕食。问题是不同的(所以不重复),但是如何从缺点单元构建列表的背景说明,以及它们是如何构建的'印刷是一样的。结尾有点不同。
Scheme中的列表是空列表()
(在某些Lisp中也称为nil
),或者是car
(也称为first
的缺点列表)是列表的一个元素,其cdr
(也称为rest
)是列表的其余部分(即另一个列表),或者是终止列表的原子。传统的终结符是空列表()
;被()
终止的列表被称为“正确列表”。被任何其他原子终止的列表称为“不正确的列表”。列表(1 2 3 4 5)
包含元素1,2,3,4和5,并由()
终止。您可以通过
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ())))))
现在,当系统打印一个缺点单元时,一般情况是通过
打印它(car . cdr)
例如,(cons 1 2)
的结果打印为
(1 . 2)
由于列表是由增量单元格构建的,因此您也可以将此表示法用于列表:
'(1 2 3 4 5) ; ==
'(1 . (2 . (3 . (4 . (5 . ())))))
但是,这是相当笨重的,所以大多数lisps(我所知道的)都有一个打印cons单元格的特殊情况:如果cdr
是一个列表(另一个cons单元格,或()
),然后不打印.
,并且不打印cdr
的周围括号(否则它将具有,因为它是一个列表)。
通过对列表和缺陷单元的理解,我们可以考虑具体案例((1 2) 3)
和((1 2) . 3)
。让我们将这些中的每一个分解为缺陷单元。
((1 2) 3) ; ==
((1 . (2 . ()) . (3 . ())) ; ==
(cons (cons 1 (cons 2 ()) (cons 3 ()))
((1 2) . 3) ; ==
((1 . (2 . ())) . 3) ; ==
(cons (cons 1 (cons 2 ())) 3)
每种情况下的最后一行都不同,因此((1 2) 3)
和((1 2) . 3)
不相同。
答案 1 :(得分:2)
不,正如其他人所提到的,((1 2) 3)
与((1 2) 3 . ())
相同,当然您可以使用(cons '3 '())
而不是文字'3
来构建:
(cons (cons '1 (cons '2 '())) (cons '3 '()))
答案 2 :(得分:1)
没有
(A . B)
的“顶级”元素是单个cons
单元格:(cons A B)
。缺点单元格的car
为A
,cdr
为B
。在正确的列表中,cdr
元素始终是()
或其他非空的正确列表。
相比之下,(A B)
是一个双元素列表,每个元素都有一个cons单元格:(cons A (cons B ()))
答案 3 :(得分:1)
他们是不同的。 ((1 2) 3)
是'()
终止列表,而((1 2) . 3)
只是“对”。尝试将'3
替换为(cons '3 '())
答案 4 :(得分:1)
他们是不同的:
(equal? '((1 2) 3) '((1 2) . 3))
=> #f
因为'((1 2) 3)
等同于此:
(cons (cons 1 (cons 2 '())) (cons 3 '()))
'((1 2) . 3)
等同于此:
(cons (cons 1 (cons 2 '())) 3)
所以你看,他们有一个不同的cons
单元结构。第一个版本是正确的列表 - 意思是:它以空列表'()
结束,而第二个版本以3
结尾,使其成为不正确的列表< / em>的