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

时间:2010-03-04 11:06:28

标签: 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)))))))

这本书的版本:

(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)))))

谢谢!

Joss Delage

2 个答案:

答案 0 :(得分:6)

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

基本上,eqan?适用于任何类型的参数,假设(1)eqlist?能够告诉对(atom?car的事物)非对(它是cdr的否定版本),(2)pair?测试原子的等式,(3)一切都是eqan?或一对或一个原子。 (好吧,实际上'()是我眼中的一个原子 - 而Petite Chez Scheme也同意。)书籍版本适用于正确的列表(包括'()),做出类似的假设,并忽略了遇到一个问题的可能性。不正确的名单。

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

答案 1 :(得分:1)

这是我的版本:

(define eqlist?
    (lambda (l1 l2)
      (cond
        ((and (null? l1) (null? l2))
         #t)
        ((and (atom? (car l1)) (atom? (car l2)))
         (and (eq? (car l1) (car l2)) (eqlist? (cdr l1) (cdr l2))))
        (else
         (and (eqlist? (car l1) (car l2)) (eqlist? (cdr l1) (cdr l2)))))))