我认为{{clojure.core/for}}的语法非常适合test.check的组合符。例如
(defn gen-even-subset
"返回一个生成器,用于生成给定元素的偶数基数子集"
"[elements]"
[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/tuple}}和更容易剪枝时使用{{gen/bind}}。一种方法是为这种功能添加一个额外的支持子句,也许称为{{: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}}功能尚未添加到当前补丁中。