Clojure core.match cannot match class
On dodging this super simple core.match expression, I get:
(match [(class "3.14")]
[Integer] "Integer"
[Double] "Doubler")
; => "Integer"
How can this be correct, I am missing something principled about core.match? Doing macro-instance-1 on this form gives me:
=> (clojure.core/let [ocr-2751 (class "3.14")] (clojure.core/let [Integer ocr-2751] "Integer"))
Any pointers appreciated.
source to share
Like @Arthur, it core.match
will usually associate values ββwith symbols. However, apparently, he first tries to match with the locals . Who knew?
Anyway, bind the classes as locals in let
before mapping, and you will find it helpful:
(let [Integer java.lang.Integer
String java.lang.String]
(match [(class "3.14")]
[Integer] "Integer"
[String] "String"))
source to share
core.match allows you to assign a name to one of the values ββin a match clause like this (from examples )
(let [x 1 y 2]
(match [x y]
[1 b] b
[a 2] a
:else nil))
In this example, if the first matching value is one, then in the expression used to generate the result, the second value will be available under the name b
.
Since any character in the match clause is interpreted as an instruction to bind the corresponding value to that name, in your case the name is Integer
bound to the valuejava.lang.String
user> (match [(class "3.14")]
[Integer] Integer
[Double] "Doubler")
java.lang.String
user> (match [(class "3.14")]
[name-to-bind] name-to-bind
[Double] "Doubler")
java.lang.String
It is not clear from the documentation that there is a way to use core.match to evaluate the match clause instead of binding to it. It is possible to work around this by matching against a string, although it loses some of the elegance:
user> (match [(str (class (int 3)))]
["class java.lang.Integer"] "Integer"
["class java.lang.String"] "String"
["class java.lang.Double"] "Double")
"Integer"
user> (match [(str (class "3.14"))]
["class java.lang.Integer"] "Integer"
["class java.lang.String"] "String"
["class java.lang.Double"] "Double")
"String"
user> (match [(str (class 3.14))]
["class java.lang.Integer"] "Integer"
["class java.lang.String"] "String"
["class java.lang.Double"] "Double")
"Double"
source to share