2010-03-04 41 views
7

我正在閱讀「Little Schemer」一書,並執行各種功能。一般來說,我最終會得到與本書相同的版本,但不是eqlist?,它是測試兩個列表相等的函數。小Schemer eqlist?功能 - 備用版本?

我試過測試我的版本,它傳遞了我扔到它的任何東西。然而,它與「小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))))) 

謝謝!

喬斯德拉赫

+0

+1從該小策士:-) – csl 2010-03-08 18:40:03

回答

6

書版將打破,如果在一個原子或不正當的名單通過(一對是不是列表 - 像(1 2 . 3))作爲參數。 (注意,它確實與'()一起工作,當然 - 不知道TLS是否認爲這是一個原子)。這使得你的函數實際上更加健壯,儘管可能更好地命名爲eqv?/equal?而不是eqlist?。 (我看equal?eqan?用於測試數值相等,但傳統上這個名字是連接到一個普世價值平等的測試功能。)

基本上,你的eqlist?適用於任何類型的參數下的假設:(1)atom?能夠從非對(它是pair?的否定版本),(2)eqan?測試原子的相等性,(3)一切是'()或一個對或一個原子來指示對(與carcdr有關的東西)。 (嗯,實際上'()是我眼中的一個原子,Petite Chez Scheme也同意這個說法。)這本書的版本適用於正確的列表(包括'()),做出了類似的假設,並且忽略了遇到不正確列表的可能性。

如果在本書稍後介紹更強大的平等測試功能,我不會感到驚訝,但我沒有它可用於檢查。無論如何,你發佈的eqlist?的書版本似乎是爲了說明列表背後的基本思想,而不是你實際上想在日常編程中使用的東西。事實上,給定版本的eqan?會在一個不受限制的環境中打破,在這個環境中需要考慮更多的原子類型的數據,其中至少需要將字符串分開計算,從而使上面第二段中列出的假設失效,並且打破eqlist?的兩個版本。

+0

太好了,謝謝你的問題。 – JDelage 2010-03-04 19:21:47

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