package au.id.zancanaro; import java.util.Random; import java.util.function.Function; public interface Generator { RoseTree generate(Random random, int size); static Generator pure(T value) { return (random, size) -> RoseTree.pure(value); } @SafeVarargs static Generator tuple(Generator... generators) { return (random, size) -> { @SuppressWarnings("unchecked") RoseTree[] result = (RoseTree[]) new RoseTree[generators.length]; int index = 0; for (Generator generator : generators) { result[index++] = generator.generate(random, size); } return RoseTree.zip(Function.identity(), result); }; } default Generator fmap(Function f) { return (random, size) -> this.generate(random, size).fmap(f); } default Generator flatMap(Function> action) { return (random, size) -> { return RoseTree.join(this.generate(random, size).fmap(action).fmap(g -> g.generate(random, size))); }; } }