我确定这一定是一个愚蠢的问题,但我该如何处理 core.logic 中的目标列表?
(run* [g]
(f))
(defn f[]
'(succeed succeed))
将抛出异常,因为run*
不需要列表。我觉得我需要做(apply all (f))
,但all
它是一个宏,所以这不起作用。
解决方案是什么?我觉得我在这里遗漏了一些微不足道的东西......
阿德里安。
我确定这一定是一个愚蠢的问题,但我该如何处理 core.logic 中的目标列表?
(run* [g]
(f))
(defn f[]
'(succeed succeed))
将抛出异常,因为run*
不需要列表。我觉得我需要做(apply all (f))
,但all
它是一个宏,所以这不起作用。
解决方案是什么?我觉得我在这里遗漏了一些微不足道的东西......
阿德里安。
这似乎有效:
(everyg succeed (f))
如果有更好或至少更惯用的解决方案,我仍然感兴趣。
如果您的目标仅采用一个参数,那么您可以按照另一个答案中的建议使用everyg 。基本上 (everygg coll) 是当目标 g 在 coll 的每个元素上成功时成功的目标。因此 coll 不是目标的集合,而是 g 的单个参数的集合。这仍然有帮助,因为与project结合使用,可以编写:
(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 还是很陌生,所以欢迎发表评论。
我还没有尝试过,但是查看http://www.clojure.net/2012/10/02/More-core.logic/似乎有类似的事情使用这个结构:
(def f (all
succeed
succeed))