在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)
对于任何x和xs.在这里,你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当与括号表示.这是一对列表.
| 归档时间: |
|
| 查看次数: |
973 次 |
| 最近记录: |