免责声明:我已经 20 年没有定期编写方案了。
我认为你想从整个 lispy/schemey 方法的角度来考虑这个问题,即建立你的条件。
给定一个输入项,您想查找列表是否包含该项。
如果列表不为空,则列表可能包含项目。
如果列表的汽车与项目匹配或列表的汽车包含项目,则列表包含项目
如果列表的 cdr 包含项目,则列表包含项目。
最后一个要考虑的问题,(part? '(a b) '(a b)) 的结果是什么?
我会这样写代码
(define part? (lambda (item l)
(cond ((null? l) f)
((or (same? item (car l)) (part? item (car l))))
(t (part? item (cdr l)))
)
))
(define same? (lambda (a b) (eq? a b)))
我使用了 cond 结构,因为它非常适合这类问题 - 解决问题感觉不错 - 请注意 null 检查。我写的一样吗?作为辅助函数,以防您想自己编写它。您可以通过这种方式轻松实现:
(define same? (lambda (a b)
(cond ((and (atom? a) (atom? b)) (eq? a b))
((and (list? a) (list? b)) (and (same? (car a) (car b)) (same? (cdr a) (cdr b))))
(f f)
)
))
这基本上说如果两个项目都是原子并且它们是 eq 或者它们都是列表并且汽车相同并且 cdr 相同,则它们是相同的,否则为假。
你可以同样轻松地重写吗?像这样:
(define same? (lambda (a b) (equal? a b)))
这样做的重点是代码中存在瓶颈-如何确定两个项目是否相同。如果你把这个瓶颈分解成它自己的功能,你可以用不同的机制来替换它。我知道你还没到这里,但你会在某一时刻:你还可以重写代码以便传入谓词。像这样的东西(以及更多最新的方案程序员,请随意纠正我):
(define part-pred? (lambda (same-pred item l)
(cond ((null? l) f)
((or (same-pred item (car l)) (part? item (car l))))
(t (part? item (cdr l)))
)
))
(define part-eq? (lambda (item l) (part-pred? 'eq? item l)))
(define part-same? (lambda (item l) (part-pred? 'same? item l)))
(define part-equal? (lambda (item l) (part-equal? 'equal? item l)))
现在,这已将 part 的概念抽象为一个函数,该函数应用 part 结构规则和由您提供的相等谓词。这使得更改规则变得非常容易。当您点击地图车时,这将更有意义。