Fork me on GitHub
#matcher-combinators
<
2023-02-02
>
Richie20:02:16

(defn match?
  [pattern data]
  (->> (mc/match (m/match-with [string? my-string-compare-fn] pattern)
                 data)
       :match/result
       (= :match)))
Is there a way that I can do something like this? It was getting out of hand when I tried to implement the Matcher protocol and I’m wondering if I’m missing some helper function that can turn my function into a matcher or something like that.

Emerson Matos20:02:41

Maybe? (match? (matchers/match-with <overrides> <expected>) <actual>) or even (match? (m/regex pattern) <actual>)

dchelimsky21:02:04

If you're trying to match against a regex, you can (match? #"Oh" "Oh, hai")

Richie21:02:06

I am trying to use match-with but I can't pass it a function. IIUC, it takes a Matcher. I have my own str= function that converts two strings to lower case and then removes all whitespace.

Richie21:02:30

My only idea on how to make it work is to make a new record implementing matcher but when I tried that it got hairy so I figured that I was doing it wrong.

dchelimsky22:02:38

I’m on my phone now, so can’t verify this, but the via matcher is probably what you want. It takes a fn to transform the actual. You shouldn’t need to do that for the expected, just supply a trimmed, downcased String literal.

Richie22:02:39

Hmm, that is helpful to know. I'm sure I'll use that in the future for something. I have this currently

(defn is-the-thing?
  [{:keys [field other]}]
  (let [[a b c] other]
    (and (some-pred? field)
         (str= "one" a)
         (str= "two" b)
         (or (str= "three" c)
             (str= "also three" c)))))
Using via I colud have
(def is-the-thing? {:field some-pred?
                    :other (m/prefix [(m/via normalize-string "one")
                                      (m/via normalize-string "two")
                                      (m/any-of (v/via normalize-string "three")
                                                (v/via normalize-string "also three"))])})
but I think I'd prefer something like this
(defn my-match?
  [pattern data]
  (->> (mc/match (m/match-with [string? ????] pattern)
                 data)
       :match/result
       (= :match)))

(def is-the-thing? {:field some-pred?
                    :other (m/prefix ["one"
                                      "two"
                                      (m/any-of "three"
                                                "also three")])})
I just don't know how to continue in that direction.

dchelimsky11:02:36

I don't see how my-match? and is-the-thing? are supposed to fit together yet. Can you please provide an example of how you'd be using this in a match? expression with literal data?

Phillip Mates14:02:17

note you have matcher-combinators.standalone/match? instead of doing

(->> (mc/match ... ...)
     :match/result
     (= :match))

Phillip Mates14:02:25

(def reverse-str (comp (fn [chars] (apply str chars)) reverse))
(s/match?
  (m/match-with [string? (fn [expected] (m/via reverse-str expected))]
                "321")
  "123")
maybe? as an example of how to match strings with their reverse

Phillip Mates14:02:37

(s/match?
  (m/match-with [string? (fn [expected]
                           (fn [actual] 
                             (= expected (reverse-str actual))))]
                "321")
  "123")
is I think another way to do it without via

Phillip Mates14:02:00

note that it will give you different mismatch messages

Phillip Mates14:02:09

pretty confusing, but with match-with [string? ???] , the ??? should be a matcher, and looking at how matchers are defined in matcher-combinators.matchers , are usually (fn [expected] core/->SomeMatcherRecord) , but since functions are interpreted by default as core/->PredMatcher (and should have form (fn [actual] ...)), you can do the trick of (fn [expected] (fn [actual] ..))

Richie15:02:49

(defn str=
  "could be hamming distance or something"
  [expected]
  (fn [actual]
    (= (string/lower-case expected)
       (string/lower-case actual))))

(defn is-match?
  "a function that customizes string comparrison"
  [pattern data]
  (s/match? (m/match-with [string? str=] pattern)
            data))

(is-match? "Sample Data"
           "SaMpLe DaTa")
Thank you! Yea, that's what I was looking for.