meander 2022-08-22

hello! I am drinking the meander koolaid and wondering how to do this transform?

;; input
{:a {:m {}
     :n {}}
 :b {:m {}
     :o {}}}

;; output
[[:a :m]
 [:a :n]
 [:a :m :n]
 [:b :m]
 [:b :o]
 [:b :m :o]]

Does this need to be arbitrarily deep? Or for only the first level of keys?

only for the first level of keys

I found the cookbook and it looks like {& (m/seqable [!ks !vs] …)} might help here

Something like this is almost right:

(m/rewrite {:a {:m {}
                :n {}}
            :b {:m {}
                :o {}}}
  [?k (m/and (m/seqable !v ...) ?v2)]
  [[?k !v] ... [?k & ?v2]]

  (m/and {} (m/gather [!k (m/app keys !v)]))
  [(m/cata [!k !v]) ...])

The trick, I think, is using m/cata to “recurse” with k and its set of keys, then doing 2 different things with those keys in the other patter

It’s possible it could all be done in the one top-level map pattern, but my brain started to get cloudy.

This isn’t quite right, though, as its got an extra layer of vector nesting per top-level key, and you didn’t want that

oh wow this is so close though, I really appreciate it

Another caveat is that m/gather acts like filter, so may or may not be what you want

oh interesting, I think that’s OK here

I was able to flatten it with m/app into:

(m/rewrite {:a {:m {}
                :n {}}
            :b {:m {}
                :o {}}}

  [?k (m/and (m/seqable !v ...) ?v2)]
  [[?k !v] ... [?k & ?v2]]

  (m/and {} (m/gather [!k (m/app keys !v)]))
  (m/app into (m/cata [!k !v]) ...))

I don’t understand the ask. How do I know that it should be :a :m :n and not :a :n :m?

I mean since maps are unordered.

good catch, the order is not essential to the solution here

What would it look like if there are multiple entries in the inner map?

Does {:a {:b {} :c {} :d {} :e {}} produce [:a :b :c] as one of the results or just [[:a :b] [:a :c] [:a d] [:a :e] [:a :b :c :d :e]] ?

I don't understand the transformation from just the one example.