2017-08-15 1 views
1

Pourquoi la dernière expression retrunsenfants vides et les fermetures à glissière Clojure

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

au lieu de:

{: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)))))) 

Il semble que le problème est lié au fait que traversant avec zip/suivant révèle qu'il y a 2 nœuds:

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

Pourquoi est-ce? Il y a un seul noeud avec des enfants vides donc il ne devrait y avoir qu'un seul noeud, correct?

Répondre

2

Après avoir regardé le code de clojure.zip/vector-zip, je conclus que le manque d'enfants du noeud doit être communiqué avec nil. La séquence vide ne fonctionne pas. donc la fonction children devrait vraiment être:

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