在SICP练习2.26中,给出了这个方案代码:
(define x (list 1 2 3))
(define y (list 4 5 6))
然后给出了这个利弊电话:
(cons x y)
我预计会产生一对列表,((1 2 3) (4 5 6))
但解释器会给出,
((1 2 3) 4 5 6)
...一个包含4个元素的列表,第一个是列表。为什么y对待不同?我已经尝试查找其他SICP答案的解释,但找不到令人满意的东西。那么,任何Scheme / Lisp专家都能对这方面的缺点有所了解吗?提前感谢任何见解。
答案 0 :(得分:12)
'((1 2 3) 4 5 6)
实际上是一对列表。这是另一种写作方式:
'((1 2 3) . (4 5 6))
但是,打印机尽可能避免使用虚线对符号,因此您可以获得第一个表示形式。规则是:
'(x . (xs ...))
=>
'(x xs ...)
适用于任何x
和xs
。在这里,您的x = '(1 2 3)
和xs = '(4 5 6)
就是((1 2 3) 4 5 6)
。
要了解缺点和点对符号是如何相关的,让我们将问题简化为'(1)
和'(6)
。构建一对它们的最低级别方法是:
(cons (cons 1 '()) (cons 6 '()))
此处,'()
为空,或空列表。如果我们将字面翻译成点对符号,我们就会得到:
'((1 . ()) . (6 . ()))
但是因为打印机尽可能折叠点对符号,所以你得到了这个:
'((1 . ()) . (6 . ()))
=>
'((1) . (6)) ; <-- x=1, xs=nothing; x=6, xs=nothing
=>
'((1) 6) ; <-- x=1, xs=6
答案 1 :(得分:10)
cons
使用第一个参数作为列表的头部,第二个参数作为尾部。
你给它一个第一个列表(1 2 3)
,它将构成结果列表的头部,第二个列表(4 5 6)
,用作列表的尾部。因此,您以((1 2 3) 4 5 6)
结束。
列表的内容为从左到右的梳子,以空列表结尾(此处表示为o
),并看看它们是如何组合的。
X= Y=
/\ /\
1 /\ + 4 /\
2 /\ 5 /\
3 o 6 o
然后构建:
/\
X Y
获得:
/\
/\ \
1 /\ \
2 /\ \
3 o/\
4 /\
5 /\
6 o
,当用括号表示时为((1 2 3) 4 5 6
。这是一对名单。
答案 2 :(得分:1)
我在学习Lisp时发现Emacs Lisp tutorial中的图表特别有用。
答案 3 :(得分:1)
只要有零,就必须有一对括号,如下:
(缺点1(缺点2)) - &gt; (清单1 2)
(let((x(list 1 2 3))(y(list 4 5 6))))
1.(cons x y) - &gt; (缺点(缺点1(缺点2(缺点3无)))(缺点4(缺点5(缺点6无)))) 这里,第一个零代表一对的结尾,可以用括号表示;而第二个零代表使用另一对括号的整对的末尾; 所以,((1 2 3)4 5 6)
2.(list x y) - &gt; (cons x(cons y nil); 因为我们知道x包含一个零,所以它必须是(1 2 3);第二部分包含两个nils, 所以((1 2 3)(4 5 6));
最内部的nil表示最外面的括号;
希望它可以提供帮助。
答案 4 :(得分:0)
答案 5 :(得分:0)
尝试(列表x y) 我确定它适用于普通的lisp,我不知道Scheme