Using an example from Clojure's test.check let
generator, generate a non-empty list of strings, give that list to another generator to pick a string from, then create a map that contains the string list and the selected string. In Clojure, it looks as follows:
(gen/let [list-of-strings (gen/not-empty (gen/list gen/string))
a-string (gen/element list-of-strings)] ;; use the generated list-of-strings above
{:all-strings list-of-strings
:selected a-string})
Taking io.kotest.property.arbitrary.bind
for inspiration, I've tried implementing it as follows, but it doesn't work (Kotlin compiler spitted out "Type inference failed"):
fun <A, B, T: Any> let(genA: Gen<A>, genB: (A) -> Gen<B>, bindFn: (A, B) -> T): Arb<T> {
return arb { rs ->
val iterA = genA.generate(rs).iterator()
generateSequence {
val a = iterA.next()
val iterB = genB(a.value).generate(rs).iterator()
val b = iterB.next()
bindFn(a.value, b.value)
}
}
}