Работа с вложенным вводом, но не выравнивание - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть функция, которая упростит что-то вроде:

(or x false) => x

Тогда определение функции принимает в качестве параметра неоцененное выражение.Я пытаюсь вложить свой ввод вот так:

(or x (and true))

Куда бы я ни посмотрел, я вижу статьи о выравнивании вложенного ввода, но в этом случае это не сработает из-за логического оператора в начале каждогоlist, поэтому самый внутренний список должен быть обработан первым, а результат будет отправлен в следующий внешний список в качестве аргумента.

Я знаю, что мне нужно вызывать свою функцию в своем собственном теле с результатом самого внутреннего списка, пока я не достигну самого внешнего списка, но я не уверен, как это сделать или что исследовать вClojure о том, как к этому.

1 Ответ

0 голосов
/ 02 октября 2018

То, что вы описываете, - это почти точно семантика оценки выражений в clojure :-), поэтому краткий ответ - запустить код :-D, хотя я подозреваю, что вы ищете более интересный ответ.

Вот простая рекурсивная версия, которая работает

  1. рекурсивно упрощает каждое вложенное выражение
  2. применяет правила упрощения к существующему выражению

Здесь в качестве примера используется слишком простое правило:

user> (defn my-eval [e]      
        (let [expanded-form (if (seq? e)
                              (map (fn [i]          
                                     (if (seq? i)    ;; if this is a sequence, 
                                       (my-eval i) ;; eval the sequence and include the result here
                                       i))         ;; otherwise use the value unchanged.
                                   e)
                              e)] ;; if it's not a seq with something in it, leve it unchanged
          (if (and
               (seq? expanded-form)
               (= (first expanded-form) 'or)
               (= 2 (count (remove false? expanded-form))))
            (second (remove false? expanded-form))
            expanded-form)))
#'user/my-eval

Сначала тест базового случая:

user> (my-eval '(or x (or y false)))
(or x y)

Затем с небольшой рекурсией:

user> (my-eval '(or (or x false) (or y false)))
(or x y) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...