2016-12-07 11 views
2

У меня есть фильтр-функция и реверс-функция сделана в моем собственном кодеОбъединение двух функций на схеме

(define reverse_ 
    (lambda (xs) 
    (if (null? xs) 
     xs 
     (append (reverse_ (cdr xs)) 
       (list (car xs)))))) 

и

(define filter_ 
    (lambda (p? xs) 
    (if (null? xs) 
     xs 
     (append (if (p? (car xs)) 
        (list (car xs)) 
        (list)) 
       (filter_ p? (cdr xs)))))) 

Я хочу, чтобы объединить две функции в (reverse-filter) то есть вы можете ввести (reverse-filter symbol? '(1 2 3 a b c)), и он вернется -> c b a.

Теперь он работает, просто набрав (reverse_ (filter_ symbol? '(1 2 3 a b c))) -> c b a, но я просто хочу совместить эти два.

Любая помощь в этом, в общем случае, и в этом конкретном одном была бы оценена

ответ

2

В общем случае, мы можем использовать curry и compose процедуры (которые, мы надеемся, которые доступны в вашем переводчика), они позволяют нам манипулировать другие процедуры:

((compose (curry filter_ symbol?) reverse_) 
'(1 2 3 a b c)) 
=> '(c b a) 

для иллюстративных целей, вот наивная реализация обоего процедур, чтобы понять, что они делают под капотом:

(define (curry f x) 
    (lambda (y) (f x y))) 

(define (compose f g) 
    (lambda (x) (f (g x)))) 
0

compose является правильным и лениво, что нужно сделать, однако, так как списки итерации от головы до хвоста, но создали из хвоста к голове создают обратный результат на самом деле более эффективны, когда сделаны на одном дыхании:

(define (reverse-filter p? xs) 
    (define (helper lst acc) 
    (if (null? lst) 
     acc 
     (helper (cdr lst) 
       (let ((a (car lst))) 
        (if (p? a) 
         (cons a acc) 
         acc))))) 
    (helper xs '())) 

(reverse-filter symbol? '(1 2 3 a b c)) 
; ==> (c b a)