7

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

(define x (list 1 2 3))
(define y (list 4 5 6))

然后给出这个 cons 调用:

(cons x y)

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

4

6 回答 6

14

'((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)


要了解 cons 和 dotted-pair notation 之间的关系,让我们将问题简化为'(1)'(6)。构建它们的最低级别的方法是:

(cons (cons 1 '()) (cons 6 '()))

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

'((1 . ()) . (6 . ()))

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

'((1 . ()) . (6 . ()))
=>
'((1) . (6))    ; <-- x=1, xs=nothing; x=6, xs=nothing
=>
'((1) 6) ; <-- x=1, xs=6
于 2010-05-27T14:24:07.973 回答
10

cons使用第一个参数作为列表的头部,第二个作为尾部。

你给它一个 first list (1 2 3),它将构成结果列表的头部和第二个 list (4 5 6),用作列表的尾部。因此,您以((1 2 3) 4 5 6).

列表的东西作为从左到右的梳子,以空列表结尾(表示为ohere),看看它们是如何组合的。

 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用括号表示时。这是一对列表。

于 2010-05-27T14:19:31.610 回答
2

嘿,我想你可以这样想;

只要有 nil,就必须有一对括号,如下所示:

(cons 1 (cons 2 nil))--> (list 1 2)

(让 ((x (列表 1 2 3)) (y (列表 4 5 6))))

1.(cons xy)--> (cons (cons 1 (cons 2 (cons 3 nil))) (cons 4 (cons 5 (cons 6 nil)))) 这里第一个nil代表一对的结束可以用括号表示;而第二个 nil 代表使用另一对括号的整个对的结尾;所以,((1 2 3)4 5 6)

2.(list xy)-> (cons x (cons y nil); 因为我们知道 x 包含一个 nil,所以它必须是 (1 2 3);第二部分包含两个 nil,所以 ((1 2 3) (4 5 6));

最里面的 nil 表示最外面的括号;

希望它可以提供帮助。

于 2011-03-17T09:17:19.610 回答
1

我发现Emacs Lisp 教程中的图表在学习 Lisp 时特别有用。

于 2010-06-11T13:57:27.983 回答
0

阅读:http ://en.wikipedia.org/wiki/Cons

于 2010-05-27T14:20:08.177 回答
0

try (list xy) 我确定它适用于 common lisp,我不知道 Scheme

于 2010-05-27T14:21:55.427 回答