Fork me on GitHub
#specter
<
2019-01-25
>
twashing10:01:38

I have a set of nested records. In my structure, I want to STAY on the i. the value nodes with :bar keys, that are ii. not seqable? and iii. not of type myns.Foo. But I can’t seem to get the recursive navigator correctly. Any ideas here?

(def a #myns.Foo{:bar #myns.Foo{:bar (#myns.Foo{:bar :a :x 1 :y 2} :b :c :d)}})

(def b (recursive-path
         [] p
         (cond-path
           seqable? [ALL p]
           [:matcher (comp clojure.core/not parser-combinator?)] (continue-then-stay ALL p)
           [:matcher (comp clojure.core/not seqable?)] [ALL p])))

(select b a)

nathanmarz15:01:56

@twashing it would be more clear if you showed desired input and output

twashing21:01:55

Hey @nathanmarz, absolutely. So I’m trying to find the recursive-path that gives me the output in *B, given the input from A*.

twashing21:01:56

;; A input structure
(defrecord Foo [bar])
(def a #user.Foo{:bar #user.Foo{:bar '(#user.Foo{:bar :a :x 1 :y 2} :b :c :d)}})

;; B output 
:a ;; (the i. the value nodes with :bar keys, that are ii. not seqable? and iii. not of type myns.Foo)

nathanmarz22:01:37

@twashing is this what you're looking for?

(def MY-WALKER
  (recursive-path [] p
    (cond-path
      #(instance? Foo %) [:bar p]
      seqable? [ALL #(instance? Foo %) p]
      STAY STAY
      )))

twashing22:01:39

@nathanmarz Hmm, if I put this into my repl, I get an empty result set.

twashing22:01:08

(use 'com.rpl.specter)

(defrecord Foo [bar])

(def a #user.Foo{:bar #user.Foo{:bar '(#user.Foo{:bar :a :x 1 :y 2} :b :c :d)}})

(def MY-WALKER
  (recursive-path [] p
    (cond-path
      #(instance? Foo %) [:bar p]
      seqable? [ALL #(instance? Foo %) p]
      STAY STAY)))

(select MY-WALKER a)

;; [] - empty result set returned

twashing22:01:19

It’s a tricky one.

nathanmarz23:01:36

@twashing probably because you meant to do (def a #user.Foo{:bar #user.Foo{:bar (#user.Foo{:bar :a :x 1 :y 2} :b :c :d)}}) ?

twashing23:01:51

Didn’t realise the reader macro stopped the list from being eval’d… Cool.

twashing23:01:27

Cheers mate. I think I have a better understanding of the semantics of if-path and cond-path.

twashing23:01:59

Although STAY STAY (to capture the leaves) is still a bit foggy.. used as both a predicate and navigator.

twashing23:01:12

Thanks for a great library!

nathanmarz23:01:35

@twashing An if-path/`cond-path` condition is "true" if it navigates to at least one value

nathanmarz23:01:43

so STAY is the navigation equivalent of true

twashing23:01:05

Gotcha :thumbsup::skin-tone-5: