To create all possible combinations of two sets of parameters and perform an action on them, you can do:
setOf(foo, bar, baz).forEach { a ->
setOf(0,
Here's another way to do it with an arbitrary combiner function:
fun product(xs: Collection, ys: Collection, combiner: (T, U) -> V): Collection =
xs.flatMap { x ->
ys.map { y ->
combiner(x, y)
}
}
operator fun Set.times(ys: Set): Set> =
product(this, ys) { x, y ->
if (x is Set<*>) x + y // keeps the result flat
else setOf(x, y)
}.toSet()
operator fun List.times(ys: List): List> =
product(this, ys) { x, y ->
if (x is List<*>) x + y // keeps the result flat
else listOf(x, y)
}.toList()
// then you can do
listOf(1, 2, 3) * listOf(true, false)
// or
setOf(1, 2, 3) * setOf(true, false)
// you can also use product's combiner to create arbitrary result objects, e.g. data classes