Преобразование в цикл ... рекурсия - PullRequest
6 голосов
/ 14 сентября 2011

Насколько я понимаю, повторение в Clojure без использования цикла. Синтаксис recur может не быть проблемой для коротких последовательностей. Тем не менее, использование цикла .. recur синтаксис является предпочтительным методом для написания рекурсивных функций. Итак, я хотел бы начать с предпочтительного метода.

Однако я изо всех сил пытался преобразовать эту функцию [править], которая возвращает каркас последовательности (структура последовательности без ее значений)

(defn skl
  [tree]
  (map skl (filter seq? tree)))

проверено с этими данными

(def test_data1 '(1 (2 3) ( ) (( )) :a))
(def test_data2 '(1 2 (3 4) (5 ( 6 7 8))))

для зацикливания .. повторный синтаксис. Любые идеи или указатели на примеры будут оценены.

Ответы [ 3 ]

4 голосов
/ 14 сентября 2011

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

3 голосов
/ 14 сентября 2011

Возможно, вы захотите заглянуть в библиотеку молний, ​​которая позволяет хорошо редактировать структурированное дерево, хотя, вероятно, будет менее элегантной, чем ваша оригинальная. Мне почти никогда не нужно использовать цикл ... повторить. Почти всегда есть функция более высокого порядка, которая решала проблему более элегантно с той же или большей эффективностью.

Замена map на loop ... recur делает код более подробным и менее понятным. Вы также теряете преимущества чанкованных последовательностей.

1 голос
/ 15 сентября 2011

Взгляните на источник clojure.walk. Это библиотека для выполнения (массовых) операций со всеми вложенными структурами данных Clojure (кроме упорядоченных карт). Там есть очень мощный, но обманчиво простой код, использующий рекурсию через локально определенные анонимные функции без использования loop / recur.

Большинство имеющихся там функций основаны на функциях postwalk и prewalk, которые в свою очередь основаны на функции прогулки. С помощью источника и (prewalk-demo form) и (postwalk-demo form) вы можете получить хорошее представление о предпринятых рекурсивных шагах.

Я не знаю, может ли это помочь вам в решении вашей проблемы. В настоящее время я пытаюсь сделать что-то в той же проблемной области: создать функцию, чтобы "сгладить" вложенные карты и векторы в последовательность всех путей от корня до листа, каждый путь - последовательность ключей и / или индексов, оканчивающихся на ' значение листа.

Эта библиотека, кажется, делает редактирование значений рекурсивно по всей структуре довольно простым. Однако я до сих пор не знаю, как использовать его для функционального отслеживания накопленных данных между итерациями, которые необходимы для моих «путей» и, вероятно, также для вашей «скелетной» проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...