В этом случае foldl
- правильный инструмент для использования (foldr
также даст правильный ответ, хотя и менее эффективно, когда делители находятся в возрастающем порядке).Идея состоит в том, чтобы взять список ввода и многократно применять к нему drop-divisible
, по одному разу для каждого элемента в списке делителей.Поскольку мы накапливаем результат между вызовами, в конце мы получим список, отфильтрованный по всем делителям.Вот что я имею в виду:
(define (sieve-with divisors lst)
; `e` is the current element from the `divisors` list
; `acc` is the accumulated result
(foldl (lambda (e acc) (drop-divisible e acc))
lst ; initially, the accumulated result
; is the whole input list
divisors)) ; iterate over all divisors
Я использовал lambda
для явного указания имен параметров, но на самом деле вы можете напрямую передать drop-divisible
.Я бы лучше написал эту более короткую реализацию:
(define (sieve-with divisors lst)
(foldl drop-divisible lst divisors))
В любом случае, она работает как положено:
(sieve-with '(2 3) '(2 3 4 5 6 7 8 9 10))
=> '(2 3 5 7)