2016-09-16 17 views
1
(define (removeAll list-a list-b) 
    (if (empty? list-b) 
    list-a 
    (apply 
     (removeAll((remove (first list-b) list-a) (rest list-b))) 
    ) 
) 
) 

(removeAll '(a b b c c d) '(a c a))試圖在Dr.Retet中實施remove *操作?

預期成果是在這種情況下

我可以使用刪除'(b b d),但我不能使用刪除*本身。目前,我得到這個錯誤: application: not a procedure; expected a procedure that can be applied to arguments given: '(b b c c d) arguments...:

回答

3

如果您在DrRacket執行程序,你會得到錯誤信息用其原因一個明顯的證據:

enter image description here

你看到的問題是內部:

((remove (first list-b) list-a) (rest list-b))) 

的原因是,在方案你不能使用括號自由像其他的語言uages:(+ 2 (+ 3 4))不等於(+ 2 ((+ 3 4))):第一表達式進行求值到9中,由於((+ 3 4))以這種方式被解釋第二給出一個錯誤:

  1. 評估內形式(表達式)(+ 3 4),即應用的操作+自變量3和4,產生7.
  2. 由於(+ 3 4)是在另一組括號內,比得到結果並嘗試評估(7)作爲一種形式。但是7而不是運算符(「不是一個過程」,如錯誤消息所示),所以會引發錯誤。

在你的情況下,remove的結果是一個列表,並且這不能用作操作符。

如果去掉雙括號,以這樣的方式

(removeAll (remove (first list-b) list-a) (rest list-b)) 

您將刪除的第一個錯誤,你會看到有另一個錯誤,特別是:

apply: arity mismatch; 
the expected number of arguments does not match the given number 
    expected: at least 2 
    given: 1 
    arguments.: 

這裏是可能的解決方案:

(define (removeAll list-a list-b) 
    (if (empty? list-b) 
     list-a 
     (removeAll (filter (lambda (x) (not (eq? (first list-b) x))) list-a) (rest list-b)))) 

函數filter刪除所有元素s不滿足謂詞。

+4

略有不同,在方案或球拍中添加parens *表達式就像在其他語言的表達式之後放置空對*。所以如果(a b)像(b)那樣,那麼((a b))就像是(b)()。這可能是合法的Java表達式......但只有當(b)返回一個沒有參數的函數時。 –

+0

@JohnClements謝謝!如此接近,但我得到''(bbcd)'而不是'(bbd)' – HelloWorld

+1

@hello,我犯了一個錯誤,認爲'remove'會刪除所有出現的元素,而只會刪除第一個出現的元素,所以我改變了我的答案 – Renzo