Как бороться со списком целей в core.logic
Я уверен, что это глупый вопрос, но как мне разобраться со списком целей в core.logic?
(run* [g]
(f))
(defn f[]
'(succeed succeed))
Выкину исключение, так как run*
не ожидает список. Я чувствую, что мне нужно сделать (apply all (f))
, но all
это макрос, так что это не работает.
Какое решение? Я чувствую, что упускаю что-то тривиально очевидное здесь...
Адриан.
3 ответа
Если ваши цели принимают только один параметр, вы можете использовать EveryG, как это предлагается в другом ответе. По сути (каждый g g coll) - это цель, которая достигает успеха, когда цель g достигает успеха для каждого элемента coll. Следовательно, coll - это не набор целей, а набор параметров для g. Это все еще помогает, потому что в сочетании с проектом это позволяет написать:
(defn applyg
[g v]
"Goal that succeeds when the goal g applied to v succeeds.
Non-relational as g must be ground."
(project [g] (everyg g [v])))
И когда есть набор целей для применения:
(defna apply-collg
[gcoll v]
([() _])
([[gh . gt] _] (applyg gh v) (apply-collg gt v)))
Используя pred для создания цели из предиката clojure, легко проверить:
(run* [q] (apply-collg [#(pred % pos?) #(pred % odd?)] 1))
=> (_0)
(run* [q] (apply-collg [#(pred % pos?) #(pred % odd?)] 2))
=> ()
Если для целей применения требуется 2 или более параметров, нужно просто преобразовать их в цели, используя один набор параметров.
Я все еще новичок в core.logic, поэтому комментарии приветствуются.
Это похоже на работу:
(everyg succeed (f))
Мне все еще интересно, есть ли лучшее или хотя бы более идиоматическое решение.
Я не пробовал этого, но, глядя на http://www.clojure.net/2012/10/02/More-core.logic/ похоже, что с использованием этой конструкции есть нечто подобное:
(def f (all
succeed
succeed))