我正在阅读“Little Schemer”这本书,并执行各种功能。通常我最终得到与书籍相同的版本,但不是 eqlist?,这是一个测试两个列表是否相等的函数。
我试过测试我的版本,它通过了我扔给它的任何东西。然而它与“Little Schemer”版本略有不同,我希望有人对我是否遗漏了什么的看法 - 我怀疑是这种情况。
我的版本:
(define eqlist?
(lambda (list1 list2)
(cond
((and (null? list1)(null? list2))#t)
((or (null? list1)(null? list2))#f)
((and (atom? list1)(atom? list2))(eqan? list1 list2))
((or (atom? list1)(atom? list2)) #f)
(else
(and(eqlist? (car list1) (car list2))
(eqlist? (cdr list1) (cdr list2)))))))
本书版本:
(define eqlist2? ;This is Little Schemer's version
(lambda (list1 list2)
(cond
((and (null? list1)(null? list2)) #t)
((or (null? list1)(null? list2)) #f)
((and (atom? (car list1))(atom? (car list2)))
(and (eqan? (car list1)(car list2))(eqlist2? (cdr list1)(cdr list2))))
((or (atom? (car list1))(atom? (car list2))) #f)
(else
(and (eqlist2? (car list1)(car list2))
(eqlist2? (cdr list1)(cdr list2)))))))
在这两种情况下, eqan 的定义是:
(define eqan?
(lambda (a1 a2)
(cond
((and (number? a1)(number? a2)) (equal? a1 a2))
((or (number? a1)(number? a2)) #f)
(else (eq? a1 a2)))))
谢谢!
乔斯·德拉格
最佳答案
如果传入一个原子或不正确的列表(一对不是列表——比如 (1 2 . 3)
)作为参数,书的版本会中断。 (请注意,它确实适用于 '()
,当然——不确定 TLS 是否认为这是一个原子。)这使您的函数实际上更健壮,尽管可能更好地命名 eqv?
/equal?
比eqlist?
. (我看到 equal?
用于 eqan?
来测试数字相等性,但传统上这个名称附加到一个通用值相等性测试函数。)
基本上,您的 eqlist?
在 (1) atom?
的假设下适用于任何类型的参数能够从非对(它是 car
的否定版本),(2) cdr
中区分对(带有 pair?
和 eqan?
的东西)测试原子的相等性,(3) 一切都是 '()
或一对或一个原子。 (嗯,实际上 '()
在我眼中是一个原子——Petite Chez Scheme 同意。)本书版本适用于正确列表(包括 '()
),做出类似的假设并忽略遇到不正确列表的可能性。
如果本书稍后介绍了更强大的相等性测试函数,我不会感到惊讶,但我没有它可供检查。反正书版eqlist?
您发布的内容似乎旨在说明列表背后的基本思想,而不是您实际想要在日常编程中使用的内容。实际上,给定的版本eqan?
会在有更多原子类型数据需要考虑的无限制环境中中断,其中至少需要单独考虑字符串,从而使上面第二段中列出的假设无效并破坏 eqlist?
的两个版本。 .
关于scheme - 小Schemer eqlist?功能 - 替代版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2378698/