meander

wilkerlucio 2021-12-04T19:21:15.075Z

hello, is there a more "meander way" to do this?

(m/find
  {:foo [{:bar "baz"}
         {:bar "baz2"}]}

  {:foo (m/app
          #(mapv (fn [x] (m/find x
                           {:bar ?bar}
                           {:tx/bar ?bar}))
             %)
          ?foos)}

  {:renamed/foo ?foos})

wilkerlucio 2021-12-04T19:22:04.075100Z

this works, just feels a bit ugly to have this sub-meander calls and have to use mapv, what I would like to is to pattern-replace each item on the collection under :foo, and get a reference to that transformed list, is there a better way to do it?

wilkerlucio 2021-12-04T19:46:10.075300Z

my best so far was to hide the mess in a defsyntax:

(m/defsyntax mmap [& patterns]
  (let [out       (first patterns)
        patterns' (next patterns)]
    `(m/app
       (fn [x#]
         (into (empty x#)
               (map (fn [i#]
                      (m/find i# ~@patterns')))
               x#))
       ~out)))
(m/find
  {:foo [{:bar "baz"}
         {:bar "baz2"}]}

  {:foo (mmap ?foos
          {:bar ?b}
          {:b ?b})}

  {:renamed/foo ?foos})

noprompt 2021-12-04T20:38:48.075500Z

Like this?

(m/rewrite {:foo [{:bar "baz"}
                  {:bar "baz2"}]}
  {:foo [{:bar !bar & !rest} ...]}
  {:renamed/foo [{:tx/bar !bar & !rest} ...]})
;; =>
#:renamed{:foo [#:tx{:bar "baz"} #:tx{:bar "baz2"}]}

noprompt 2021-12-04T20:42:57.075700Z

You could also do the same thing with a bottom-up strategy:

(let [s (m*/bottom-up
         (m*/rewrite {:foo (m/some ?foo)}
                     {:renamed/foo ?foo}

                     {:bar (m/some ?bar) & ?rest}
                     {:tx/bar ?bar & ?rest}

                     ?x ?x))]
  (s {:foo [{:bar "baz"} {:bar "baz2"}]}))
;; =>
#:renamed{:foo [#:tx{:bar "baz"} #:tx{:bar "baz2"}]}

noprompt 2021-12-04T20:47:39.076100Z

Similarly, if you don't want to involve strategy, you can use m/cata

(m/rewrite {:foo [{:bar "baz"}
                  {:bar "baz2"}]}

  [(m/cata !x) ...]
  [!x ...]

  {:foo (m/and (m/some) (m/cata ?foo))}
  {:renamed/foo ?foo}

  {:bar (m/some ?bar) & ?rest}
  {:tx/bar ?bar & ?rest}

  ?x ?x)
#:renamed{:foo [#:tx{:bar "baz"} #:tx{:bar "baz2"}]}

noprompt 2021-12-04T20:48:43.076300Z

And if you don't want to use m/rewrite you can still use m/find with manual control over the right side

(m/find {:foo [{:bar "baz"}
               {:bar "baz2"}]}

  [(m/cata !x) ...]
  !x

  {:foo (m/and (m/some) (m/cata ?foo))}
  {:renamed/foo ?foo}

  {:bar (m/some ?bar) & ?rest}
  (merge {:tx/bar ?bar} ?rest)

  ?x ?x)
;; =>
#:renamed{:foo [#:tx{:bar "baz"} #:tx{:bar "baz2"}]}

noprompt 2021-12-04T20:49:07.076500Z

Does this help?

wilkerlucio 2021-12-04T23:18:40.076700Z

gotcha, yes, it does, the first rewrite is the thing, its surprising to me how Meander is able to get it right, but it does 😄

1