Как переместить молнию на левый / правый узел в clojure? - PullRequest
0 голосов
/ 27 января 2019

Я пишу дерево (дерево решений бизнес-процессов) в структуре данных clojure.

(require clojure.zip :as z)

(z/vector-zip 
    [ :billed?  
        [:yes  
            [:check-bank-account] 
            [:check-cash] ] 
        [:send-out-email] ])

когда код переходит на первый узел, он считывает ключевое слово и выполняет определенные действия, результатом будет True или False, тогда я бы хотел перейти на left (True) или right (Ложный) узел.

Когда мой код начинается с корневого узла и вызывает некоторую функцию, связанную с :billed?, он возвращает True, как может clojure перейти в узел :yes или :send-out-email узел?Я думал, что есть только z/down, в то время как left или right только для братьев и сестер, а не для указаний детей.

Большое спасибо за ваше время и ценим любые мысли

Ответы [ 2 ]

0 голосов
/ 27 января 2019

Молнии проходят через структуру данных, отслеживая текущую позицию. Чтобы добраться до разных узлов, вы должны применить последовательность ходов к одной и той же молнии. Когда создается молния, ваша позиция находится прямо над деревом:

(z/node tree)
=> [:billed? [:yes [:check-bank-account] [:check-cash]] [:send-out-email]]

Таким образом, вы можете спуститься в дерево с помощью z/down и использовать z/node, чтобы получить текущий узел из местоположения молнии:

(-> tree
    z/down
    z/node)
=> :billed?

Если вы идете по дереву сверху по направлению к какому-то узлу, вам, вероятно, нужны только z/down и z/right, так как при спуске в дочерний вектор вы окажетесь у самого левого дочернего элемента. Это проще представить, если вы поместите вектор в плоскую линию и представите, что z/right просто перемещает курсор на следующий элемент, а z/down перемещает курсор на внутри вектора.

(-> tree
    z/down
    z/right
    z/node)
=> [:yes [:check-bank-account] [:check-cash]]

(-> tree
    z/down
    z/right
    z/right
    z/node)
=> [:send-out-email]

Вот пример того, как вы могли пройти по этому дереву, сравнивая ключи с картой фактов:

(def tree
  (z/vector-zip
    [:billed?
     [:wire-funds?
      [:check-bank-account]
      [:check-cash]]
     [:send-out-email]]))

(defn facts->action [facts]
  (loop [curr (z/down tree)]
    (let [node (z/node curr)]
      (if-let [fact (find facts node)]
        (if (val fact)
          (recur (-> curr z/right z/down)) ;; descend "left"
          (recur (-> curr z/right z/right z/down))) ;; descend "right"
        node))))

(facts->action {:billed? false})
=> :send-out-email
(facts->action {:billed? true :wire-funds? true})
=> :check-bank-account
(facts->action {:billed? true :wire-funds? false})
=> :check-cash
0 голосов
/ 27 января 2019

Цепные множественные движения на молнии.

Вот пример:

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

(def zipper (z/vector-zip
              [:billed?
               [:yes
                [:check-bank-account]
                [:check-cash]]
               [:send-out-email]]))

(println (-> zipper z/down z/right z/down z/node))
(println (-> zipper z/down z/right z/down z/right z/down z/node))
...