The s/or spec conforms to [flag value] – where flag is the name given in s/or 
to the spec that matches (to produce the value). s/and flows the conformed 
result of the first spec into the remaining specs, so ::testcc is being passed 
a vector with two elements instead of the map you are trying to conform.

You can either add (s/conformer second) so that the conformed s/or result is 
unpacked (to get just the value) or you can wrap the ::test spec in a call to 
the (undocumented) s/nonconforming function which returns the original, rather 
than the conformed value:

(s/and ::test (s/conformer second) ::testcc)

(s/and (s/nonconforming ::test) ::testcc)

Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

________________________________
From: [email protected] <[email protected]> on behalf of Philipp 
Neumann <[email protected]>
Sent: Monday, May 28, 2018 10:00:22 AM
To: Clojure
Subject: Clojure Spec question with and/or composition

Hi.


I hope this is the right place for Spec questions.
I try to composite different specs with and/or (I tried Google, but searching 
for and/or is useless :/):



(s/def ::testa #{"a"})
(s/def ::testb #{"b"})
;;;(sdef+ ::testaa {:a ::testa})
(do
 (clojure.spec.alpha/def
 :data$testaa/a
 :data/testa)
 (clojure.spec.alpha/def
 :data/testaa
 (clojure.spec.alpha/keys
 :req-un
 (:data$testaa/a))))
;;;(sdef+ ::testbb {:b ::testb})
(do
 (clojure.spec.alpha/def
 :data$testbb/b
 :data/testb)
 (clojure.spec.alpha/def
 :data/testbb
 (clojure.spec.alpha/keys
 :req-un
 (:data$testbb/b))))
;;;(sdef+ ::testcc {:c ::testb})
(do
 (clojure.spec.alpha/def
 :data$testcc/c
 :data/testb)
 (clojure.spec.alpha/def
 :data/testcc
 (clojure.spec.alpha/keys
 :req-un
 (:data$testcc/c))))
(s/def ::test (s/or ::testaa ::testaa ::testbb ::testbb))
(s/def ::test2 (s/and ::test ::testcc))
(s/describe ::test2)

(s/conform ::test {:b "b" :c "b"})
;[:data/testbb {:b "b", :c "b"}]
(s/conform ::testcc {:b "b" :c "b"})
;{:b "b", :c "b"}

(s/explain ::test2 {:b "b" :c "b"})


{:b "b" :c "b"} is valid? for ::test and ::testcc, but not for the combination 
of them with (s/and ::test ::testcc).
I did all the intermediate specs, to decouple the specs with map-keywords 
without namespaces (I wanted the spec to work with legacy maps).
I obviously do something wrong, but I don't know how to improve on this.

Kind Regards

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to 
[email protected]<mailto:[email protected]>.
For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to