Использование Reduce над деревом в Лиспе

Чтобы сложить плоский список в Лиспе, вы используетеreduce:

* (reduce #'+ '(1 2 3 4 5))
15

Но что, если у меня произвольно сложное дерево, и я хочу применить функцию к каждому элементу? Так что переверни'(1 (2) (3 (4) 5)) все равно даст15? Я пытался использоватьreduce, но я должен был предоставить пользовательскую функцию, которая как бы побеждает цель:

(defun tree+ (a b)
  (cond ((null b) 0)
        ((atom b) (+ a b))
        (t (+ (tree+ a (car b))
              (tree+ 0 (cdr b))))))

(reduce #'tree+ '(1 (2) (3 (4) 5)) :initial-value 0) ; returns 15

Конечно, я мог бы сначала сгладить список, ноreduce это общая функция, иногда вы должны сохранить структуру и порядок исходной последовательности. Например,map а такжеfilter может быть реализован сreduce, Что если бы я хотел написать реализациюmy-mapна основеreduce, чтобы:

(my-map '1+ '(1 (2 (3) 4) 5)) ; outputs '(2 (3 (4) 5) 6)

Как пользоватьсяreduce над древовидной структурой? Какой самый общий способ применения бинарной функции к дереву?

Ответы на вопрос(3)

Ваш ответ на вопрос