2024 Clojure 状况调查!分享您的想法。

欢迎!请参阅关于页面了解更多关于此信息的工作方式。

0
core.logic

这可能与 core.logic 如何打印向量结构有关。

以下是重现问题的最小示例

(ns testclj.logic
(:require (link: clojure.core.logic :as l)))

(def data (link: [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[:a)]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]])

(time (l/run* (link: q) (l/== q data)))

2 个回答

0

评论由:troydm 提出

我认为问题与以下代码段有关

`
(defn walk* [s v]
(let [v (walk s v)]

(walk-term v
  (fn [x]
    (let [x (walk s x)]
     (if (tree-term? x)
       (walk* s x)
       x))))))

`

另一方面则调用

`
clojure.lang.IPersistentVector
(walk-term [v f])

(with-meta
  (loop [v v r (transient [])]
    (if (seq v)
      (recur (next v) (conj! r (walk-term (f (first v)) f)))
      (persistent! r)))
  (meta v)))

`

这会递归地为向量的所有元素调用 walk-term。
然后为向量的每个元素调用 walk-term,这反过来又会调用 walk* 过去访问过的向量元素。
结果导致多次回到子节点。

整体结果是将子节点多次访问。

问题是 walk 函数部分递归地调用 walk 为 walk-term 函数调用的先前遍历的向量元素。

`
(if (tree-term? x)

       (walk* s x)
       x)

`

我认为这部分的整体设计有很大的问题,我不确定在这里可以提出什么建议,但我认为我们需要将 walk-term 和 walk* 合并成一个函数,一次性遍历整个数据结构,有什么建议吗?

可能的解决方案如下代码,但我不确定它是否正确

`
(defn walk* [s v]
(let [v (walk s v)]

(walk-term v
    #(walk s %))))

`

0
参考:[https://clojure.atlassian.net/browse/LOGIC-177](https://clojure.atlassian.net/browse/LOGIC-177)(由alex+import报告)
...