Задача состоит в том, чтобы написать функцию фильтра только с одним вызовом foldr без рекурсии или любых других процедур более высокого порядка (map, andmap, apply и т. Д.).

В настоящее время я использую

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

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

Цель - иметь

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

С одним вызовом foldr

1
Chase 20 Фев 2016 в 00:58

2 ответа

Лучший ответ

Я думаю, вы неправильно понимаете, как работает foldr, вам нужно передать list для обработки в качестве последнего параметра, а для реализации фильтра примените 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)
3
Óscar López 19 Фев 2016 в 22:23

Это похоже на домашнее задание. Я могу понять, почему был выбран 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 в том, что он реализован с правильным хвостовым вызовом.

0
Thank you 20 Фев 2016 в 02:09