我认为 {{clojure.core/for}} 的语法非常适合 test.check 的组合符。例如
(defn gen-even-subset
"返回一个生成器,它生成给定元素的偶数基数子集"
[elements]
(>> (gen/for [bools (apply gen/tuple (repeat (count elements) gen/boolean))
:let [true-count (->> bools (filter identity) (count))]
:when (even? true-count)]
(->> (map list bools elements)
filter first)
map second)
(set))))
这结合了 {{fmap}}、{{bind}} 和 {{such-that}} 的功能,并使用熟悉的语法。
这里的缺点是,可能会倾向于使用多个独立的生成器的从句,从而导致使用 {{gen/bind}},而实际上 {{gen/tuple}} 更简单且可能更容易缩小。对此的一种方法是添加一个额外的支持从句,可能称为 {{:parallel}},它使用 {{:let}} 的语法来提供 {{gen/tuple}} 的功能
(gen/for [:parallel [n1 gen/nat
n2 gen/nat]
:let [sum (+ n1 n2)]]
{:nums [n1 n2] :sum sum})
与 {{gen/tuple}} 相比,这个优点是将生成器在语法上放置在名称旁边,而不是将生成器与名称隔离开。
{{:parallel}} 功能尚未添加到当前补丁中。