I want to "get back" from a value to its schema. lets say I have: a valid instance of Address:
{:id "H7",
:tags #{:v?.w.t6!.QJYk-/-?s*4
:_7U
:QdG/Xi8J
:*Q-.p*8*/n-J9u}
:address {:street "V9s"
:city ""
:zip 3
:lonlat [-2.75 -0.625]}}
How can I find(programaticaly) the "schema" of :longlat for example.
-> should tell me '[:tuple :double :double]'
(when knowing that it is from the schema Address, defined as:
(def Address
[:map
[:id :string]
[:tags [:set :keyword]]
[:address
[:map
[:street :string]
[:city :string]
[:zip :int]
[:lonlat [:tuple :double :double]]]]])This is how you can access sub-schemas:
user=> (mu/get-in Address [:address :lonlat])
[:tuple :double :double]For your use case you might want to iterate over subschemas using something like mu/subschemas or m/children
my overall goal is to programmitcaly "compare two adresses", and the way to compare each "leave value" depends on its "type". (two strings/keywords get compared differently then two :enum values)
I happen to be experimenting with something similar, does this look helpful? https://github.com/frenchy64/malli/blob/f15d235ff9aaaf35583b34f1001f294090ca5ad9/test/malli/shrinker_test.cljc#L431
here's one way to use it to write a diff algorithm that tells you which schema differs https://github.com/frenchy64/malli/blob/f15d235ff9aaaf35583b34f1001f294090ca5ad9/test/malli/shrinker_test.cljc#L291-L317
I'm mentioning this not because you should use it yet, but more because I haven't found anything generic enough for this so I'm building my own.
I was steering for 2 hours to two "equal vectors", which looked equal, but "=" compared them as false. And then I printed the class... (-> call-result (get [:domain] :annotation) :schema class) ;;=> malli.core$enumschema$reify$reify__13444 (-> fixed (get [:domain] :annotation) :schema class) ;;=> clojure.lang.PersistentVector So something in malli "prints like a vector" but is not comparing as a vector.
It happens when using mali/walk
The schema in the call-back fn, is (for :enum) at least of this reify type, which "looks like a vector", but is not.
; :schema [:enum :de :fr :it] :schema-class malli.core$enumschema$reify$reify__13444
; :schema [:enum :cold :hot :warm :cool] :schema-class malli.core$enumschema$reify$reify__13444
I think I was assuming, that this is true, but's its not: (= [:enum :a] (m/schema [:enum :a])) -> false
schema returns a Schema instance (given a Schema form or a Schema instance
form return a Schema form (i.e. the data representation of a schema)
Yes, I was just surprised, as I am new to malli, that a malli schema does not "=" to its "form" representation, and that even two schemas from the same vector are not "=" (as they print equal) Now I know it.
Maybe teh docu could be more explicit abou it, that
(= :string (m/schema :string)) -> false
(= :string (m/form (m/schema :string))) -> true