clojure-spec

About: http://clojure.org/about/spec Guide: http://clojure.org/guides/spec API: https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html
william 2021-04-12T09:15:53.022100Z

what would be the most idiomatic way to spec a graph structure? I would want something around (`graph` is the loom library):

(s/def ::my-graph
      (s/and
       graph/directed?
       #(not= :cljs.spec.alpha/invalid (s/conform (s/coll-of ::my-node) (graph/nodes %)))))

william 2021-04-12T09:16:13.022500Z

but I find that predicate quite cumbersome to write

william 2021-04-12T09:24:58.023100Z

(s/def ::my-graph
      (s/and
       graph/directed?
       #(s/valid? (s/coll-of ::my-node) (graph/nodes %))))
is a bit better. Is there anything better still?

borkdude 2021-04-12T10:01:27.023500Z

@meditans not an answer to your question, but in general: instead of = :cljs.spec.alpha/invalid use (s/invalid? ...)

🙌 1
borkdude 2021-04-12T10:02:30.024Z

I think you should be able to leave out s/valid? and just pass a spec

william 2021-04-12T11:42:58.024100Z

but how would I also invoke graph/nodes ?

em 2021-04-12T18:05:54.024400Z

What does your graph data structure look like? Is it some kind of custom data type, and therefore it requires the graph/nodes accessor?

em 2021-04-12T18:06:24.024600Z

@meditans If it's just a map, which is preferred in most situations, you can just spec a :graph/nodes key while also getting all the benefits of spec for your other graph metadata

william 2021-04-12T19:10:10.024800Z

the data structure is the one in the loom library. (graph/nodes %) is the invocation of the function that gives the nodes back

2021-04-12T20:22:51.025Z

One potential option is to use a conformer in your s/and to handle the conversion into your specable form: https://clojuredocs.org/clojure.spec.alpha/conformer

(s/and graph/directed?
       (s/conformer graph/nodes)
       (s/coll-of ::my-node))