1

为什么最后一个表达式会重新运行

{:a :foo, :args [{:id :XX}], :id :XX}

代替:

{:a :foo, :args [], :id :XX}

(require '[clojure.zip :as zip])

(defn my-zipper [tree]
  (zip/zipper
    (fn branch? [node]
      (:args node))
    (fn children [node]
      (:args node))
    (fn make-node [node children]
      (assoc node :args (vec children)))
    tree))

(def z (my-zipper {:a :foo :args []}))

(loop [loc z]
  (if (zip/end? loc)
    (zip/node loc)
    (recur
      (zip/next 
         (zip/edit loc #(assoc % :id :XX))))))

看起来问题与使用 zip/next 遍历显示有 2 个节点的事实有关:

(zip/node (zip/next z))             ;  => nil
(zip/node (zip/next (zip/next z)))  ;  => {:a :foo :args []} 

这是为什么?有一个带有空子节点的节点,所以应该只有一个节点,对吗?

4

1 回答 1

2

在查看了 clojure.zip/vector-zip 的代码后,我得出结论认为缺少节点的孩子应该与nil. 空序列不起作用。所以children函数应该是:

(fn children [node]
      (seq (:args node)))
于 2017-08-15T14:40:55.840 回答