在使用DrScheme的SICP练习2.26中,为什么cons会返回一个列表,而不是一对列表?

时间:2010-05-27 14:17:13

标签: scheme sicp

在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专家都能对这方面的缺点有所了解吗?提前感谢任何见解。

6 个答案:

答案 0 :(得分:12)

'((1 2 3) 4 5 6)实际上是一对列表。这是另一种写作方式:

'((1 2 3) . (4 5 6))

但是,打印机尽可能避免使用虚线对符号,因此您可以获得第一个表示形式。规则是:

'(x . (xs ...))
=>
'(x xs ...)

适用于任何xxs。在这里,您的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