Задача deep-substitute
- заполнить шаблон формы и вернуть ее.Проблема усложняется, если вы попытаетесь сделать deep-substitute
также ответственным за выполнение следующего шага в преобразованиях.Возможно, пусть оно вернет значение, а затем передаст это значение другой функции преобразования после того, как оно будет возвращено.
Вот аннотированный рабочий пример:
user> (defn deep-substitute [m l]
(map (fn [i]
(if (seq? i) ;; if this is a sequence,
(deep-substitute m i) ;; finish the sequence and include the result here
(get m i i))) ;; otherwise get the new value from the map, if found
l)) ;; if it's not found, us the value unchanged.
#'user/deep-substitute
, а затем протестируйте его на своем примере:
user> (deep-substitute '{x false, y true} '(or false x y))
(or false false true)
и более вложенный пример:
user> (deep-substitute '{x false, y true} '(or false (and x (or y x)) y))
(or false (and false (or true false)) true)
общий следующий шаг - обернуть его в макрос, чтобы он мог изменять формы перед их оценкой, а затем оценивать вновь созданные из ввыясните, какое значение это становится:
user> (defmacro dsub [m l]
(deep-substitute m l))
#'user/dsub
и протестируйте его
user> (dsub {x false, y true} (or false (and x (or y x)) y))
true
user> (dsub {x false, y true} (or false x))
false
или передайте полученную форму (без оценки) в другую функцию, вложив ее:
user> (defn f [expression]
(reverse expression))
#'user/f
user> (f (deep-substitute '{x false, y true} '(or false (and x (or y x)) y)))
(true (and false (or true false)) false or)
Распространенным шаблоном является использование потоковых макросов ->
->>
и т. Д. Для передачи результата от преобразования к преобразованию до получения окончательного результата путем составления множества простых операций:
user> (->> '(or false (and x (or y x)) y)
(deep-substitute '{x false, y true})
f
(deep-substitute '{false, 41 true 42}))
(42 (and 41 (or 42 41)) 41 or)