如何为带有序列参数的函数编写Clojure Spec?

时间:2018-09-11 14:55:52

标签: clojure clojure.spec

我正在编写一个函数,该函数采用一系列三角形(实际上表示为maps)。

我的规格是:

(s/fdef triangle-list-to-pattern
        :args (s/cat :trs (s/* ::maths/Triangle))
        )

该函数采用单个参数trs,它是三角形的序列。

但是,当我检测该函数并调用它时,出现以下错误:

fails spec: :patterning.maths/Triangle at: [:args :trs] predicate: map?

如果我使用spec明确测试要传递给函数的参数,则参数将通过。确实,这只是一系列符合三角形标准的事情。

该功能似乎正在起作用。该参数似乎是正确的,并且在单独测试时通过了规范。所以我想我以某种方式弄错了fdef

出什么问题了?

注意,::三角已定义:

(s/def ::Triangle (s/keys :req-un [::A ::B ::C ::a ::b ::c ::ax ::ay ::bx ::by ::cx ::cy]))

1 个答案:

答案 0 :(得分:3)

您的:args规范不起作用的原因是regex specs构成了嵌套时描述一个序列。

您可以通过将内部正则表达式规范s/*封装在s/spec中来逃避此行为:

(s/cat :trs (s/spec (s/* ::maths/Triangle)))

或使用其他非正则表达式规范来描述sequence参数:

(s/cat :trs (s/coll-of ::maths/Triangle))

如果函数是可变参数,则示例规范工作,因为s/cats/*组成了一个具有零个或多个元素的单个序列的构成。

(defn adder [& nums] (apply + nums))
(s/fdef adder :args (s/cat :nums (s/* int?)))
(st/instrument `adder)
(adder 1 2 3)