2016-02-19 53 views
1

目的是在沒有遞歸或任何其他高階過程(map,andmap,apply等)的情況下只用一個foldr調用來編寫過濾器函數。使用單個foldr調用寫入過濾器?

目前,我不過是用它被認爲是一個高階的程序

的目標是有

(filter positive? '(-1 2 3 4 -5 -6)) 
=> '(2 3 4) 

與foldr相似的單一調用andmap功能使用

(define (filter ps xs) 
    (if (empty? xs) 
     ps 
     (foldr (lambda (p y) 
       (if (andmap p xs) 
        (cons p y) 
        y)) 
       '() 
       ps))) 

回答

3

我想你誤會了foldr的作品,你必須通過列表作爲最後一個參數進行處理,並且爲了實現過濾器,對每個要測試的元素應用ps。更好的嘗試是這樣的:

(define (filter ps xs) 
    (foldr (lambda (p y) 
      (if (ps p) 
       (cons p y) 
       y)) 
     '() 
     xs)) 

它按預期工作:

(filter positive? '(-1 2 3 4 -5 -6)) 
=> '(2 3 4) 
+0

如果ps是一個包含過程的列表,那麼我如何實現它,以便返回的列表僅保留對所有過程都爲真的元素?我只能使用一次foldr的調用。 – Chase

+0

這很麻煩,你必須遍歷'if'條件中的過程列表。用'(和map(lambda(f)(fp))ps''替換'(ps s)'' –

+0

好吧,那會是一個問題,我只能使用一次調用foldr而沒有別的東西(不能使用和映射並且沒有遞歸),否則它會減少很多混淆。 – Chase

0

這聽起來像一個家庭作業。我可以看到,爲什麼foldr選擇,但看到起見,用foldl在這裏實現你去

(define (filter f xs) 
    (reverse (foldl (λ (x ys) (if (f x) (cons x ys) ys)) 
        null 
        xs))) 

(filter positive? '(-1 2 3 4 -5 -6)) 
;=> '(2 3 4) 

foldl具有明顯的優勢foldr,它與一個適當的尾調用執行。