2

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?

Setzer22
  • 1,589
  • 2
  • 13
  • 29

1 Answers1

3

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)))]
OlegTheCat
  • 4,443
  • 16
  • 24