JDe*_*age 7 scheme the-little-schemer
我正在阅读"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)))))))
Run Code Online (Sandbox Code Playgroud)
这本书的版本:
(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)))))))
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,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)))))
Run Code Online (Sandbox Code Playgroud)
谢谢!
乔斯德拉格
如果传入一个原子或一个不正确的列表(一对不是列表 - 就像(1 2 . 3))作为参数传递,书籍版本就会中断.(注意它确实可以使用'()- 当然 - 不确定TLS是否认为它是一个原子.)这使得你的函数实际上更加健壮,尽管可能更好地命名eqv?/ equal?比eqlist?.(我看到equal?用于eqan?测试数字相等,但传统上这个名称附加到通用值相等测试函数.)
基本上,你eqlist?在任何类型的论证下工作的假设是:(1)atom?能够用非对((它是否定的版本)来表示对(带有car和的东西),(2)测试原子的等式,(3)一切都是一对或一对或一个原子.(好吧,实际上是我眼中的一个原子 - 而且Petite Chez Scheme也同意.)书籍版本适用于正确的列表(包括),做出类似的假设,并忽略了遇到不正确列表的可能性.cdrpair?eqan?'()'()'()
如果在本书后面提出了更强大的相等测试功能,我不会感到惊讶,但我没有它可以检查.无论如何,eqlist?你发布的书籍版本似乎是为了说明列表背后的基本思想,而不是你真正想要在日常编程中使用的东西.实际上,给定的版本eqan?会在一个不受限制的环境中中断,在这种环境中需要考虑更多的原子类型的数据,其中至少需要单独考虑字符串,从而使上面第二段中列出的假设无效并打破两个版本的eqlist?.