In my program, I'm using a kind of matrix (as a vector of vectors) like this one:
[[:lt :lt :gt :eq]
[:eq :lt :gt :eq]
[:eq :eq :gt :gt]
[:un :eq :lt :lt]]
I have a schema for it, declared as:
(def OrderMatrix [[(s/enum :lt :eq :gt :un)]]
What I'd like to do is further restrict the schema so it makes sure my matrix is a vector of clojure.lang.PersistentVector, or even better (if possible), a structure that supports random access. It seems that using [ ] in schema only tests for sequence, so a list of lists would pass the schema as well.
How do I express this constraint with schema?
You may use combination of schema/both
and schema/pred
. Here's an example:
(defn Vector [inner-schema]
(schema/both (schema/pred vector? "vector")
[inner-schema]))
(defn RandomAccess [inner-schema]
(schema/both
(schema/pred
(partial instance? java.util.RandomAccess)
"random access")
[inner-schema]))
(def OrderMatrix (Vector (Vector (schema/enum :lt :eq :gt :un))))
;; or (def OrderMatrix (RandomAccess (RandomAccess (schema/enum :lt :eq :gt :un))))
and then:
user> (schema/check OrderMatrix ['(:lt)])
[(not ("vector" (:lt)))]