小Schemer eqlist?功能 - 备用版本?

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)

谢谢!

乔斯德拉格

Mic*_*zyk 6

如果传入一个原子或一个不正确的列表(一对不是列表 - 就像(1 2 . 3))作为参数传递,书籍版本就会中断.(注意它确实可以使用'()- 当然 - 不确定TLS是否认为它是一个原子.)这使得你的函数实际上更加健壮,尽管可能更好地命名eqv?/ equal?eqlist?.(我看到equal?用于eqan?测试数字相等,但传统上这个名称附加到通用值相等测试函数.)

基本上,你eqlist?在任何类型的论证下工作的假设是:(1)atom?能够用非对((它是否定的版本)来表示对(带有car和的东西),(2)测试原子的等式,(3)一切都是一对或一对或一个原子.(好吧,实际上是我眼中的一个原子 - 而且Petite Chez Scheme也同意.)书籍版本适用于正确的列表(包括),做出类似的假设,并忽略了遇到不正确列表的可能性.cdrpair?eqan?'()'()'()

如果在本书后面提出了更强大的相等测试功能,我不会感到惊讶,但我没有它可以检查.无论如何,eqlist?你发布的书籍版本似乎是为了说明列表背后的基本思想,而不是你真正想要在日常编程中使用的东西.实际上,给定的版本eqan?会在一个不受限制的环境中中断,在这种环境中需要考虑更多的原子类型的数据,其中至少需要单独考虑字符串,从而使上面第二段中列出的假设无效并打破两个版本的eqlist?.