Существует ли такая процедура в стандарте Scheme, и если да, то как она называется?
Вопрос
Я искал имя процедуры, которая применяет древовидную структуру процедур к древовидной структуре данных, получая древовидную структуру результатов - все три дерева имеют одинаковую структуру.
Такая процедура может иметь подпись:
(map-tree data functree)
Его возвращаемое значение будет результатом поэлементного применения элементов дерева функций к соответствующим элементам данных.
Примеры (при условии, что процедура называется деревом карт):
Пример 1:
(define *2 (lambda (x) (* 2 x))) ; and similar definitions for *3 and *5 (map-tree '(100 (10 1)) '(*2 (*3 *5)))
дало бы результат
(200 (30 5))
Пример 2:
(map-tree '(((aa . ab) (bb . bc)) (cc . (cd . ce))) '((car cdr) cadr))
дает результат
((aa bc) cd)
Однако я не нашел такой функции в документации SLIB, с которой ознакомился.
Существует ли уже такая процедура?
Если нет, то какое имя было бы подходящим для процедуры и как бы вы упорядочили ее аргументы?
Решение
У меня не очень хорошее имя для этой функции.Я вставляю свою реализацию ниже (я назвал ее map-traversing
;другие должны предложить лучшее имя).Я сделал порядок аргументов зеркальным map
сам.
(define (map-traversing func data)
(if (list? func)
(map map-traversing func data)
(func data)))
Используя ваш пример данных, мы имеем:
(map-traversing `((,car ,cdr) ,cadr) '(((aa . ab) (bb . bc)) (cc cd . ce)))
Для второго образца требуется SRFI 26.(позволяет писать (cut * 2 <>)
вместо (lambda (x) (* 2 x))
.)
(map-traversing `(,(cut * 2 <>) (,(cut * 3 <>) ,(cut * 5 <>))) '(100 (10 1)))
Самое главное, что все ваши функции не должны быть заключены в кавычки, в отличие от вашего примера.
Другие советы
Я обнаружил, что при следующем определении обхода карты вам не нужно выводить функции из кавычек:
(define (map-traversing func data) (if (list? func) (map map-traversing func data) (apply (eval func (interaction-environment)) (list data))))
Примечание:в моей установленной версии Guile по какой-то причине только (среда взаимодействия) не вызывает ошибку Unbound переменной.Другие среды, т.е.(scheme-report-environment 5) и (null-environment 5) вызывают эту ошибку.
Заметка 2:Впоследствии я обнаружил в [1], что для того, чтобы (scheme-report-environment 5) и (null-environment 5) работали, вам нужно сначала (use-modules (ice-9 r5rs))
[1]: http://www.mail-archive.com/bug-guile@gnu.org/msg04368.html 'Ре:guile -c "(схема-отчет-среда 5)" ==> ОШИБКА:Несвязанная переменная:схема-отчет-среда'