#racket #higher-order-functions
#racket #функции более высокого порядка
Вопрос:
Это моя домашняя работа, но нам разрешено использовать только filter, map, foldr, sort, build-list и lambda вместо явной рекурсии
Как я могу переписать эти функции, используя вышеперечисленные функции высокого порядка, чтобы не позволить функции вызывать саму себя.
Сейчас у меня есть следующие:
(define (worthless loc name)
(cond
[(empty? loc) loc]
[(equal? name (coin-name (first loc))) (cons (make-coin (coin-name (first loc)) 0) (worthless (rest loc) name))]
[else (cons (first loc) (worthless (rest loc) name))]))
(define (working-group locations group-tz)
(cond
[(empty? locations) empty]
[(and (equal? (utc-hours group-tz) (utc-hours (location-timezone (first locations)))) (equal? (utc-sign group-tz) (utc-sign (location-timezone (first locations)))))
(cons (location-city (first locations)) (working-group (rest locations) group-tz))]
[(and (equal? (add1 (utc-hours group-tz)) (utc-hours (location-timezone (first locations))))
(equal? (utc-sign group-tz) (utc-sign (location-timezone (first locations))))
(equal? (utc-mins group-tz) (utc-mins (location-timezone (first locations)))))
(cons (location-city (first locations)) (working-group (rest locations) group-tz))]
[(and (equal? (sub1 (utc-hours group-tz)) (utc-hours (location-timezone (first locations))))
(equal? (utc-sign group-tz) (utc-sign (location-timezone (first locations))))
(equal? (utc-mins group-tz) (utc-mins (location-timezone (first locations)))))
(cons (location-city (first locations)) (working-group (rest locations) group-tz))]
[else (working-group (rest locations) group-tz)])) ```
Ответ №1:
Да. worthless
можно переписать с map
помощью . Представьте, что у нас есть эта функция, которая добавляет 3 к каждому элементу в списке:
(define (add3 lst)
(if (null? lst)
'()
(cons ( (car lst) 3)
(add3 (cdr lst)))))
Карта для одного списка выглядит следующим образом:
(define (map f lst)
(if (null? lst)
'()
(cons (f (car lst))
(map f (cdr lst))))
Глядя на них, вы можете видеть, что add3
с помощью карты нужно сосредоточиться только на добавлении 3. По сути, вам нужно передать функцию с одним аргументом, который добавляет 3 к этому аргументу:
(define (add3-wm lst)
(map (lambda (v) ( v 3)) lst))
Теперь foldr
для одного списка выглядит так:
(define (foldr f init lst)
(if (null? lst)
init
(f (car lst)
(foldr f init (cdr lst)))))
Здесь вы видите, что cons
это не сделано, поэтому для перезаписи add3
с использованием foldr
требуется объединитель, и ему нужно добавить 3 к первому аргументу и объединить два аргумента, где второй аргумент является результатом того же процесса с более поздними элементами.
(define (add3-fr lst)
(define (combiner v acc)
(cons ( v 3) acc))
(foldr combiner '() lst))
На самом деле использование foldr
here — это перебор, но было бы интересно, если бы вам иногда нужно было пропустить элемент, подобный working-group
does . В этом случае объединитель просто возвращает второй аргумент. Вы можете сделать filter
с помощью foldr
:
(define (filter f lst)
(foldr (lambda (v acc)
(if (f v)
(cons v acc)
acc))
'()
lst))
Удачи вам