Как я могу просто использовать функции высокого порядка, чтобы переписать их (используйте Dr.Racket)

#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))
 

Удачи вам