Combine monads with test.check generators to build them up out of smaller generators with dependencies:
(require ‘[clojure.test.check.generators :as gen])
(require ‘[clojure.algo.monads :as m])
[n (gen/choose 1 10)
v (gen/vector gen/int n)
e (gen/element v)]
;; ([[0 0] 0]
[[0 -1 1 0 -1 0 -1 1] 0]
[[1 1 3 3 3 -1 0 -2 2] 3]
[[8 4] 8]…
The generator here chooses a vector length, uses that to generate a vector, uses that to pick an element inside the vector, and then returns a tuple of the vector and the element. The syntax is cleaner than a lot of gen/bind and gen/fmap calls. It looks a lot like ScalaCheck.
I suspect we could define m-zero and m-plus in the monad to get :when conditions as well.
I’m working on a longer post that explains what’s going on here and why we would do it.