Reputation: 27206
I'm writing a function that takes a sequence of Triangles (which are in fact represented as maps
).
My spec is :
(s/fdef triangle-list-to-pattern
:args (s/cat :trs (s/* ::maths/Triangle))
)
And the function takes a single argument, trs which is a sequence of Triangles.
However, when I instrument this function and call it I get the following failure :
fails spec: :patterning.maths/Triangle at: [:args :trs] predicate: map?
If I explicitly test the argument I'm passing to the function with spec, it passes. It really is just a sequence of things that meet the Triangle criteria.
The function seems to be working. The argument seems to be correct, and passes the spec when tested separately. So I presume I'm getting the fdef
wrong somehow.
What's the problem?
Note, ::Triangle is defined :
(s/def ::Triangle (s/keys :req-un [::A ::B ::C ::a ::b ::c ::ax ::ay ::bx ::by ::cx ::cy]))
Upvotes: 3
Views: 260
Reputation: 16194
The reason your :args
spec isn't working is that regex specs compose to describe a single sequence when nested.
You can escape this behavior by wrapping your inner regex spec s/*
in s/spec
:
(s/cat :trs (s/spec (s/* ::maths/Triangle)))
Or use a different, non-regex spec to describe the sequence argument:
(s/cat :trs (s/coll-of ::maths/Triangle))
Your example spec would work if your function was variadic, because s/cat
and s/*
are composing to describing a single sequence with zero or more elements.
(defn adder [& nums] (apply + nums))
(s/fdef adder :args (s/cat :nums (s/* int?)))
(st/instrument `adder)
(adder 1 2 3)
Upvotes: 4