如何为采用序列参数的函数编写 Clojure 规范?

How do I write a Clojure Spec for a function that takes a sequence argument?

我正在编写一个接受一系列三角形(实际上表示为 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?

如果我明确测试传递给带有规范的函数的参数,它就会通过。它实际上只是满足三角形标准的一系列事物。

该功能似乎有效。该论点似乎是正确的,并且在单独测试时通过了规范。所以我想我弄错了fdef

有什么问题?

注意,::三角形定义为:

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

您的 :args 规范不起作用的原因是 regex specs 在嵌套时组合描述单个序列。

您可以通过将内部正则表达式规范 s/* 包装在 s/spec:

中来避免此行为
(s/cat :trs (s/spec (s/* ::maths/Triangle)))

或使用不同的非正则表达式规范来描述序列参数:

(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)