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

lim*_*ist 6 scheme sicp

在SICP练习2.26中,给出了这个方案代码:

(define x (list 1 2 3))
(define y (list 4 5 6))
Run Code Online (Sandbox Code Playgroud)

然后给出这个利弊电话:

(cons x y)
Run Code Online (Sandbox Code Playgroud)

我预计会产生一对列表,((1 2 3) (4 5 6))但解释器会给出 ((1 2 3) 4 5 6) 一个包含4个元素的列表,第一个是列表.为什么y对待不同?我已经尝试查找其他SICP答案的解释,但找不到令人满意的东西.那么,任何Scheme/Lisp专家都能对这方面的缺点有所了解吗?提前感谢您的任何见解.

Nat*_*ers 12

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

'((1 2 3) . (4 5 6))
Run Code Online (Sandbox Code Playgroud)

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

'(x . (xs ...))
=>
'(x xs ...)
Run Code Online (Sandbox Code Playgroud)

对于任何xxs.在这里,你x = '(1 2 3)xs = '(4 5 6),让您得到((1 2 3) 4 5 6).


要了解cons和点对符号是如何相关的,让我们将问题简化为just '(1)'(6).构建一对它们的最低级别方法是:

(cons (cons 1 '()) (cons 6 '()))
Run Code Online (Sandbox Code Playgroud)

这里'()是零或空列表.如果我们将字面翻译为点对符号,我们得到:

'((1 . ()) . (6 . ()))
Run Code Online (Sandbox Code Playgroud)

但是因为打印机尽可能折叠点对符号,所以你得到了这个:

'((1 . ()) . (6 . ()))
=>
'((1) . (6))    ; <-- x=1, xs=nothing; x=6, xs=nothing
=>
'((1) 6) ; <-- x=1, xs=6
Run Code Online (Sandbox Code Playgroud)


ton*_*nio 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
Run Code Online (Sandbox Code Playgroud)

然后你建立:

 /\
X  Y
Run Code Online (Sandbox Code Playgroud)

获得:

  /\
 /\ \
1 /\ \
 2 /\ \
  3  o/\
     4 /\
      5 /\
       6  o
Run Code Online (Sandbox Code Playgroud)

这是((1 2 3) 4 5 6当与括号表示.这是一对列表.