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

发布于 2024-09-03 01:15:53 字数 367 浏览 6 评论 0原文

在 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 答案以获取解释,但找不到令人满意的内容。那么,是否有任何计划/Lisp 专家可以阐明这方面的缺点?预先感谢您的任何见解。

In SICP exercise 2.26, this Scheme code is given:

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

Then this cons call is given:

(cons x y)

I expected a pair of lists would result, ((1 2 3) (4 5 6)) but the interpreter gives,
((1 2 3) 4 5 6)
...a list with 4 elements, the first being a list. Why is y treated differently? I've tried looking up other SICP answers for an explanation, but couldn't find something satisfactory. So could any Scheme/Lisp experts please shed some light on this aspect of cons? Thanks in advance for any insight.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

兲鉂ぱ嘚淚 2024-09-10 01:15:53

'((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 和点对符号之间的关系,我们将问题简化为 '(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

'((1 2 3) 4 5 6) is actually a pair of lists. Here's another way to write it:

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

However, the printer avoids dotted pair notation whenever it can, so you get the first representation instead. The rule is:

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

For any x and xs. Here, your x = '(1 2 3) and xs = '(4 5 6), so you get ((1 2 3) 4 5 6).


To see how cons and dotted-pair notation is related, let's shorten the problem to just '(1) and '(6). The lowest level way to build a pair of them is this:

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

Here, '() is nil, or the empty list. If we translate this literally to dotted-pair notation, we get this:

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

But because the printer collapses dotted-pair notation whenever possible, you get this instead:

'((1 . ()) . (6 . ()))
=>
'((1) . (6))    ; <-- x=1, xs=nothing; x=6, xs=nothing
=>
'((1) 6) ; <-- x=1, xs=6
戏蝶舞 2024-09-10 01:15:53

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。这是一对列表。

cons uses the first argument as head of the list, and the second as tail.

You give it a first list (1 2 3), which will constitute the head of the resulting list and a second list (4 5 6), to be used as tail of the list. Thus, you end with ((1 2 3) 4 5 6).

Thing of lists as left-to-right combs, ending with empty list (represented as o here), and see how they combine.

 X=      Y=
 /\      /\
1 /\  + 4 /\    
 2 /\    5 /\  
  3  o    6  o

You then build:

 /\
X  Y

Obtaining:

  /\
 /\ \
1 /\ \
 2 /\ \
  3  o/\
     4 /\
      5 /\
       6  o

which is ((1 2 3) 4 5 6 when represented with parenthesis. And this is a pair of lists.

清引 2024-09-10 01:15:53

嘿,我想你可以这样想;

每当有 nil 时,就必须有一对括号,如下所示:

(cons 1 (cons 2 nil))--> (列表 1 2)

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

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

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

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

希望它能有所帮助。

hey, i think you could think of it in this way;

whenever there is a nil, there must be a pair of parenthesis, as follow:

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

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

1.(cons x y)--> (cons (cons 1 (cons 2 (cons 3 nil))) (cons 4 (cons 5 (cons 6 nil))))
here, the first nil stands for an end of a pair which could be expressed by parenthesis; whereas the second nil stands for the end of the whole pair which use another pair of parenthesis;
so, ((1 2 3) 4 5 6)

2.(list x y)-> (cons x (cons y nil);
as we know the x contain a nil, so it must be (1 2 3); the second part contains two nils,
so ((1 2 3) (4 5 6));

the inner most nil means the outer most parenthesis;

Hope it can help.

抚你发端 2024-09-10 01:15:53

我在 中找到了这些图表Emacs Lisp 教程 在学习 Lisp 时特别有帮助。

I found the diagrams in the Emacs Lisp tutorial particularly helpful when learning Lisp.

苍暮颜 2024-09-10 01:15:53

尝试(列出xy)
我确信它可以在 common lisp 上运行,我不知道 Scheme

try (list x y)
I'm sure it works on common lisp, I don't know about Scheme

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文