Fork me on GitHub
#clojure
<
2023-09-04
>
adham18:09:28

Is spec the right tool for the following case: Check if the input of a function is a member of a vector, e.g. (func "A") where the arg has to be either A, B or C. I'm trying to learn spec from the spec guide but the only mention of something similar is using s/coll-of.

phill18:09:08

This part is relevant

(s/valid? #{:club :diamond :heart :spade} :club) ;; true

adham18:09:19

Yes, but I've failed to incorporate this into spec and a function with s/fdef

(defn func [arg] arg)
(s/fdef func 
        :arg (s/cat :arg #{:club :diamond :heart :spade}))
(func :foo) ; => :foo

Bob B19:09:23

I think you just want :args rather than :arg in the fdef:

(defn frob [x] x)
(spec/fdef frob :args (spec/cat :thing #{"a" "b" "c"}))
(st/instrument `frob)
(frob "b")
;; => "b"
(frob "d")
;; Execution error - invalid arguments...

adham19:09:08

Correct, in addition to the typo my CIDER repl was broken for some reason (e.g. no error with your example), restarting made it work.

adham19:09:38

Does :thing not have to be called :x like the argument parameter? Didn't know that

Bob B19:09:04

afaik it's not strictly necessary, but it does probably make sense in most cases - I was just slapping together the other details

adham19:09:03

Understood, thank you for your time!