Применение списка функций к списку значений в Racket - PullRequest
2 голосов
/ 09 марта 2019

Я новичок в Racket и языке схем в целом, и мне трудно реализовать мои идеи.

По сути, у меня есть список функций (давайте назовем его List f) и список строк (давайте назовем его List s). Что мне нужно сделать, так это выполнить для каждой функции в f функцию и сохранить значение в другом списке (пусть call это List done).

Например: скажем, у меня есть List A = (f1 f2) и List B = (a b c), я бы выполнил:

f1 a
f1 b
f1 c
f2 a
f2 b
f2 c

и все они добавят свои значения в List done

Я также не могу использовать любую форму set в ракетке.

Я понимаю, как это должно работать, и могу легко закодировать это на C или Java, но схема доставляет мне неприятности.

1 Ответ

3 голосов
/ 09 марта 2019

В Racket есть много встроенных процедур, которые облегчают решение проблем, связанных с манипулированием списками. Например, вы ищете for*/list:

(define A (list string-upcase string-downcase))
(define B (list "Aa" "Bb" "Cc"))

(define done
  (for*/list ([f A] [s B])
    (f s)))

Он перебирает все элементы в A, присваивая каждый из них по очереди переменной f. И во вложенном цикле он также перебирает все элементы в B, присваивая каждый из них по очереди переменной s. В теле цикла он применяет каждый f ко всем s и собирает все в выходной список. Теперь done содержит ожидаемые значения:

done
=> '("AA" "BB" "CC" "aa" "bb" "cc")

Если бы мы делали это вручную, используя рекурсию, было бы больше работы. Возможная реализация будет иметь процедуру для выполнения «внешнего» цикла, который будет вызывать другую процедуру для выполнения «внутреннего» цикла. Третья процедура запускает рекурсию и объединяет результаты:

(define (outer-loop funcs params)
  (if (null? funcs)
      '()
      (cons (inner-loop (car funcs) params)
            (outer-loop (cdr funcs) params))))

(define (inner-loop f params)
  (if (null? params)
      '()
      (cons (f (car params))
            (inner-loop f (cdr params)))))

(define (apply-funcs funcs params)
  (apply append ; required to "flatten" the list of lists
         (outer-loop funcs params)))

Мы бы использовали это так:

(define done (apply-funcs A B))

Сначала вы должны научиться решать проблемы со списком вручную, используя собственные циклы. Убедившись, что вы понимаете, что делаете, потратьте некоторое время на изучение существующих процедур списка и итераций и пониманий , идиоматического способа использования языка в реальной жизни. .

...