diff options
author | Carlo Zancanaro <carlo@zancanaro.id.au> | 2015-05-30 02:00:43 +1000 |
---|---|---|
committer | Carlo Zancanaro <carlo@zancanaro.id.au> | 2015-05-30 02:00:43 +1000 |
commit | d29e1d49116c66adab72b1c1bb49c1fa3d4f8140 (patch) | |
tree | 17363b0d5b939c217cc95e4c57326e01c45d121e /src/main/java/au/id/zancanaro/Generator.java |
Initial commit: only works for plain int typed arguments
Diffstat (limited to 'src/main/java/au/id/zancanaro/Generator.java')
-rw-r--r-- | src/main/java/au/id/zancanaro/Generator.java | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/main/java/au/id/zancanaro/Generator.java b/src/main/java/au/id/zancanaro/Generator.java new file mode 100644 index 0000000..4b80e51 --- /dev/null +++ b/src/main/java/au/id/zancanaro/Generator.java @@ -0,0 +1,51 @@ +package au.id.zancanaro; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.function.Function; + +public interface Generator<T> { + RoseTree<T> generate(Random random, int size); + + static <T> Generator<T> pure(T value) { + return (random, size) -> RoseTree.pure(value); + } + + default <R> Generator<R> genFlatmap(Function<RoseTree<T>, Generator<R>> f) { + return (random, size) -> { + RoseTree<T> inner = this.generate(random, size); + Generator<R> generator = f.apply(inner); + return generator.generate(random, size); + }; + } + + default <R> Generator<R> genFmap(Function<RoseTree<T>, RoseTree<R>> f) { + return (random, size) -> f.apply(this.generate(random, size)); + } + + @SafeVarargs + static <T> Generator<T[]> tuple(Generator<T>... generators) { + return (random, size) -> { + @SuppressWarnings("unchecked") + RoseTree<T>[] result = (RoseTree<T>[]) new RoseTree[generators.length]; + int index = 0; + for (Generator<T> generator : generators) { + result[index++] = generator.generate(random, size); + } + return RoseTree.zip(Function.identity(), result); + }; + } + + default <R> Generator<R> fmap(Function<T, R> f) { + return (random, size) -> this.generate(random, size).fmap(f); + } + + default <R> Generator<R> flatMap(Function<T, Generator<R>> action) { + return this.genFlatmap(rose -> { + Generator<RoseTree<R>> generator = (random, size) -> + rose.fmap(action).fmap(g -> g.generate(random, size)); + return generator.<R>genFmap(RoseTree::join); + }); + } +} |