空儿童和Clojure拉链

时间:2017-08-15 13:53:50

标签: clojure zipper

为什么最后一个表达式重新出现

{: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 []} 

为什么?有一个空节点的单个节点,所以应该只有一个节点,对吗?

1 个答案:

答案 0 :(得分:2)

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

(fn children [node]
      (seq (:args node)))