Open reedrosenbluth opened 6 years ago
Zip is overloaded so you can combine up to three Gens, so your example can be written as.
Gen<Cylinder> cs = radii().zip(heights(), colours(), (r,h,c) -> new Cylinder(r,h,c));
So things currently start to get ugly at four.
This needs to be extended to support more values but it needs to stop somewhere (6?), at which point the best solution is probably to fix the modelling of the type being generated.
I'm open to suggestions of other ways the api could allow Gens to be combined.
You might consider having a generator for "tuples" of various arities, such that you might then write:
Gen<Cylinder> cs = tuples(radii(), heights(), colours()).map((r,h,c) -> new Cylinder(r,h,c));
This is approximately the same as your zip()
method, but it seems somewhat cleaner to have all three components of a Cylinder represented at the same level, as arguments to a tuple-generator.
Also, consider the following code snippet:
private static Gen<RGBColor> colors() {
return doubles().between(0, 1).map((r, g, b) -> RGBColor.color(r, g, b));
}
It's super cool to be able to map a scalar onto a tuple-type like this. When you do this, however, IntelliJ helpfully highlights the lambda, saying "lambda can be replaced with a method reference". Unfortunately, because map
is overloaded for lambdas of different arities, IntelliJ's helpful code rewriter generates this:
private static Gen<RGBColor> colors() {
return doubles().between(0, 1).map((Function3<Double, Double, Double, RGBColor>) RGBColor::color);
}
Suggestion: how about having methods called map2
, map3
, and so forth, either in addition to or instead of the overloading of map
? This would avoid the need for the verbose typecast.
Is there a cleaner syntax for creating a Gen for a type with more than 2 properties than what I have below? This starts to get ugly for types with more properties...