Scheme中car与cdr链式组合是否有限制?为何缩写形式报错?
Scheme中car/cdr缩写的使用规则与报错原因
你的报错根源:缩写的字母顺序完全搞反了
你写的caadadadadadadr开头是连续两个a(对应两次car操作),但目标列表'(1(2(3(4(5(6(7))))))的第一个元素是1——这是个原子值,不是列表,对它执行car操作直接触发错误。
另外你提到的嵌套代码,严格按照你写的(car(car(cdr(...))))执行的话,最后一步是对7执行car,同样会报错。正确取出7的嵌套调用应该是交替执行cdr和car(从cdr开始,最后以car收尾),代码如下:
(display (car(cdr(car(cdr(car(cdr(car(cdr(car(cdr(car(cdr '(1(2(3(4(5(6(7))))))))))))))))))
car/cdr缩写的正经规则
所有Scheme标准(R5RS/R6RS/R7RS)对这类缩写的定义很清晰:
- 格式必须是
c+ 1到N个a(car的首字母)或d(cdr的首字母) +r,比如cadr、caddr这类都是合规的。 - 字母顺序是外层操作到内层操作的顺序:比如
cadr对应(car (cdr x))——先执行内层的cdr,再执行外层的car,所以缩写里把外层的a放在前面,内层的d放在后面。
简单说,如果你有嵌套调用(f1 (f2 (f3 x))),每个f是car或cdr,那对应的缩写就是c[f1的首字母][f2的首字母][f3的首字母]r。
所以正确取出7的缩写应该是cadadadadadadr——中间的a和d交替排列,对应从外层到内层的car、cdr、car、cdr...操作。
关于链式组合的限制
Scheme标准本身对car/cdr的嵌套次数没有限制,但部分Scheme解释器只预定义了短长度的缩写(比如最多4个中间字母的),超长的缩写不会自动生成,这时候你可以手动定义:
(define cadadadadadadr (lambda (x) (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr x)))))))))))))
定义后就能正常使用这个缩写了。
内容的提问来源于stack exchange,提问作者briskBuilding
相关产品推荐
相关产品推荐

