meander

All things about https://github.com/noprompt/meander Need help and no one responded? Feel free to ping @U5K8NTHEZ
ezmiller77 2020-03-26T01:17:28.003Z

Can anyone help me understand what the error “non exhaustive pattern match” means?

jimmy 2020-03-26T01:23:04.003700Z

It means your pattern didn't match. If you copy your data and code here we can help

noprompt 2020-03-26T02:15:01.003800Z

There’s also map-of and submap-of which will kinda sorta work like scan.

noprompt 2020-03-26T02:15:52.004200Z

> Like `clojure.core/case`, if no patterns match an exception will be thrown. https://github.com/noprompt/meander/blob/epsilon/doc/operator-overview.md#match

ezmiller77 2020-03-26T03:42:11.004600Z

Thanks!

jimmy 2020-03-26T04:10:50.004800Z

And gather which is like filter. I think many places people are using scan they could use gather and not use search.

👍 1
yuhan 2020-03-26T06:58:28.005800Z

(m/rewrite [1 2 3]
  [?v ...]
  [?v ...])
Weird, this throws a "non-exhaustive pattern match" compile error

yuhan 2020-03-26T07:00:18.006900Z

versus the error given by m/match:

(m/match [1 2 3]
  [?v ...]
  :ok)
=>
Zero or more patterns may not have references to unbound logic variables.
   {:unbound #{?v}, :syntax-trace [(?v ...) [?v ...]]}
(which isn't that informative either)

grounded_sage 2020-03-26T09:15:40.012Z

What would you say is best practice for picking apart a large deeply nested json (with quite a bvit of data on the first level) transform where the end result is multiple CSV’s with id’s to relate to one another. To give context my pattern and action is a total of 138 lines in a single rewrite transform. Options layed out in front of me are. • Do a single pass with rewrite, then pass that result to some matches and searches • Do one big search where the first level data is needlessly repeated in the output.. • Do the matches and searches without using rewrite • Or do all the work in the rewrite I’m leaning towards the first or last one

grounded_sage 2020-03-26T10:03:24.013100Z

Oh I just thought of a neat feature that would be nice. If not already in Meander.. haha. Use my pattern as my action. For quick inspection of the result.

grounded_sage 2020-03-26T10:04:28.013800Z

I often copy paste my pattern to my action to see what the result is before I work on more custom outputs.

grounded_sage 2020-03-26T11:53:47.018Z

How do I go about flattening this.

(m/rewrite
   {:Sales {:Overall {:TicketCount ?sales-ticket-count
                      :Amount ?sales-amount}
            :ByCategory [{:Name !category-name
                          :TicketCount !ticket-counts
                          :Amount !amounts
                          :ByReduction [{:Name !reduction-name
                                         :TicketCount !ticket-count
                                         :Amount !amount}
                                        ..!sale-reductions]}
                         ..!sale-categories]}}
   
   {:sales-by-category [{:Name !category-name
                         :TicketCount !ticket-counts
                         :Amount !amounts
                         & [{:reduction-name !reduction-name
                             :reduction-ticket-count !ticket-count
                             :reduction-amount !amount} ..!sale-reductions]}
                        ..!sale-categories]})

grounded_sage 2020-03-26T11:54:05.018400Z

Such that the result looks like this.

{:sales-by-category [{:Name "category-1"
                        :TicketCount "10"
                        :Amount "100"
                        :reduction-name "student"
                        :reduction-ticket-count "7"
                        :reduction-amount "70"}
                       {:Name "category-1"
                        :TicketCount "10"
                        :Amount "100"
                        :reduction-name "senior"
                        :reduction-ticket-count "3"
                        :reduction-amount "30"}
                       {:Name "category-2"
                        :TicketCount "20"
                        :Amount "200"
                        :reduction-name "student"
                        :reduction-ticket-count "20"
                        :reduction-amount "10"}
                       ..!sale-categories]}

yuhan 2020-03-26T14:43:35.018700Z

Huh, just realised that syntax errors like

(m/rewrite 1 ?a) 
also produce "non-exhaustive pattern match" errors instead of complaining about a missing subst-pattern argument. I don't recall it behaving like this before?

jimmy 2020-03-26T15:59:21.019300Z

Sadly not everything the exists on the left-hand-side works on the right-hand-side. So this would only work for something things.

jimmy 2020-03-26T15:59:57.019500Z

But in zeta we actually do have ability to generate data based on a pattern. So you can actually supply a pattern and have data automatically generated for you

jimmy 2020-03-26T16:00:45.019700Z

I do think we need nice inspection tools for what you’ve matched though.

jimmy 2020-03-26T16:02:55.019900Z

If you can provide some input data as well I can more easily give you an example.

jimmy 2020-03-26T16:05:01.020100Z

Although as I’m looking at your example it might be tricky. Not sure till I play with it.

grounded_sage 2020-03-26T16:29:22.021100Z

Sorry. That’s my normal go to. Providing something that can be done at the repl.

grounded_sage 2020-03-26T16:39:17.021300Z

Here is one you can plug straight into the repl.

(m/rewrite {:Sales {:Overall {:TicketCount 500
                                :Amount 20000}
                      :ByCategory [{:Name "Frontrow"
                                    :TicketCount 200
                                    :Amount 8000
                                    :ByReduction [{:Name "Student"
                                                   :TicketCount 20
                                                   :Amount 100}
                                                  {:Name "Senior"
                                                   :TicketCount 100
                                                   :Amount 289}]}
                                   {:Name "Middle"
                                    :TicketCount 240
                                    :Amount 8890
                                    :ByReduction [{:Name "Student"
                                                   :TicketCount 220
                                                   :Amount 103}
                                                  {:Name "Senior"
                                                   :TicketCount 105
                                                   :Amount 289}]}]}}
             {:Sales {:Overall {:TicketCount ?sales-ticket-count
                                :Amount ?sales-amount}
                      :ByCategory [{:Name !category-name
                                    :TicketCount !ticket-counts
                                    :Amount !amounts
                                    :ByReduction [{:Name !reduction-name
                                                   :TicketCount !ticket-count
                                                   :Amount !amount}
                                                  ..!sale-reductions]}
                                   ..!sale-categories]}}
             
             {:sales {:ticket-count ?sales-ticket-count
                      :amount ?sales-amount}
              :sales-by-category [{:Name !category-name
                                   :TicketCount !ticket-counts
                                   :Amount !amounts
                                   & [{:reduction-name !reduction-name
                                       :reduction-ticket-count !ticket-count
                                       :reduction-amount !amount}]}
                                  ..!sale-categories]})

grounded_sage 2020-03-26T16:40:20.021500Z

I could also be approaching this entirely the wrong way and maybe that could be handled by doing another meander transform on a subset of the data.

jimmy 2020-03-26T18:32:58.022100Z

(m/rewrite data

  {:Name ?category-name
   :TicketCount ?ticket-counts
   :Amount ?amounts
   :ByReduction [{:Name !reduction-name
                  :TicketCount !ticket-count
                  :Amount !amount}
                 ...]}

  [{:Name ?category-name
    :TicketCount ?ticket-counts
    :Amount ?amounts
    :reduction-name !reduction-name
    :reduction-ticket-count !ticket-count
    :reduction-amount !amount}
   ...]

  {:Sales {:Overall {:TicketCount ?sales-ticket-count
                     :Amount ?sales-amount}
           :ByCategory [(m/cata [!categories ...]) ...]}}
  {:sales {:ticket-count ?sales-ticket-count
           :amount ?sales-amount}
   :sales-by-category [!categories ...]})

jimmy 2020-03-26T18:33:55.022300Z

I couldn't think of a way of doing this without using cata.

jimmy 2020-03-26T18:34:48.022500Z

Well, of course you can break it up into multiple matches. But since you want the categories to repeat, we need them not to be in memory variables. This is a good way to do that.

noprompt 2020-03-26T18:36:40.022700Z

@grounded_sage How about this? https://gist.github.com/noprompt/d94e99ba0deb980d64522dba6a61600f

noprompt 2020-03-26T18:39:30.022900Z

The trick here is to use cata on each item in the :ByReduction sequence to do the rewriting of those items before dumping their contents into :sales-by-category

jimmy 2020-03-26T18:41:26.023100Z

@noprompt lol

noprompt 2020-03-26T18:47:31.023300Z

OMG I just noticed Jimmy posted the same answer. 😂

grounded_sage 2020-03-26T18:54:55.023500Z

I see. So it also doesn’t matter about the order?

noprompt 2020-03-26T18:55:58.023700Z

In terms of the rule ordering?

grounded_sage 2020-03-26T18:56:39.023900Z

In Jimmy’s answer he put the !categories transformations above the main pattern and action. You have it after.

noprompt 2020-03-26T19:05:57.024100Z

Oh, no, at least not in this case.

grounded_sage 2020-03-26T19:06:30.024300Z

I figured it out after looking at it for long enough and the reference one in the docs.

grounded_sage 2020-03-26T19:06:58.024500Z

I was confused as to how it determined what datastructure is the output. But it’s the one making use of the variables of course 🙂

grounded_sage 2020-03-26T19:08:04.024700Z

Slowly getting there lol

noprompt 2020-03-26T19:08:55.024900Z

Awesome! 🙂

jimmy 2020-03-26T19:14:21.025100Z

Yeah, in this case it doesn't matter, but it could if the patterns were overlapping. Then there are tricks to differentiate them. We use some of those tricks in zeta.

grounded_sage 2020-03-26T19:56:21.025300Z

Side question. What is cata short for?

grounded_sage 2020-03-26T20:10:38.028400Z

Cool. Yea those things you just described sound great :)

jimmy 2020-03-26T20:20:10.030Z

catamorphism

jimmy 2020-03-26T20:20:56.030200Z

Basically think of it like "pretend I already did recursion and match on that". That is what we are doing here.

👍 1