我已经在Scheme中分配了一个任务(使用DrRacket),该任务要求我使用cons从组件1、2、3和()中创建列表((1 2)3)。
我设法使用以下方法达到了((1 2)。3):
(cons (cons '1 (cons '2 '())) '3)
但是,那是同一回事吗?
最佳答案
注意:这是从my answer到Recursive range in Lisp adds a period?的同类。这个问题有所不同(因此不是重复的),但是有关如何从cons单元构造列表以及如何打印列表的背景说明是相同的。结束有点不同。
Scheme中的列表可以是空列表()
(在某些Lisps中也称为nil
),或者是cons单元格,其car
(也称为first
)是列表的元素,并且cdr
(也称为rest
)是列表的其余部分(即另一个列表),或终止列表的原子。传统的终止符是空列表()
;以()
终止的列表被称为“适当列表”。被其他原子终止的列表称为“不正确的列表”。列表(1 2 3 4 5)
包含元素1、2、3、4和5,并以()
终止。您可以通过构建它
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ())))))
现在,当系统打印一个cons单元格时,通常的情况是通过
(car . cdr)
例如,
(cons 1 2)
的结果打印为(1 . 2)
由于列表是由cons单元构成的,因此您也可以将这种符号用于列表:
'(1 2 3 4 5) ; ==
'(1 . (2 . (3 . (4 . (5 . ())))))
但是,这相当笨拙,因此大多数lisps(我所知道的)都有打印cons单元格的特殊情况:如果
cdr
是列表(另一个cons单元格或()
),则不要打印.
,并且不要打印cdr
的括号(否则它会带有括号,因为它是一个列表)。了解了list和cons单元后,我们可以考虑
((1 2) 3)
和((1 2) . 3)
的具体情况。让我们将这些分割为con单元格。((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)
不相同。关于scheme - (((1 2)3)与((1 2)。3)相同吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19223336/