diff --git a/vavr/generator/Generator.scala b/vavr/generator/Generator.scala index e00aa167a..7bf446494 100644 --- a/vavr/generator/Generator.scala +++ b/vavr/generator/Generator.scala @@ -98,7 +98,8 @@ def generateMainClasses(): Unit = { val PredicateType = im.getType("java.util.function.Predicate") val SupplierType = im.getType("java.util.function.Supplier") - val monadicTypesFor = List("Iterable", OptionType, FutureType, TryType, ListType) + val monadicTypesFor = List("Iterable", OptionType, FutureType, TryType, ListType, EitherType, ValidationType) + val monadicTypesThatNeedParameter = List(EitherType, ValidationType) def genTraversableAliases(traversableType: String, returnType: String, name: String) = xs""" // -- $name @@ -772,12 +773,15 @@ def generateMainClasses(): Unit = { ${monadicTypesFor.gen(mtype => (1 to N).gen(i => { val forClassName = if (mtype == "Iterable") { s"For$i" } else { s"For$i$mtype" } - val generics = (1 to i).gen(j => s"T$j")(", ") - val params = (1 to i).gen(j => s"$mtype ts$j")(", ") + val isComplex = monadicTypesThatNeedParameter.contains(mtype) + val parameterInset = (if (isComplex) {"L, "} else "") + val generics = parameterInset + (1 to i).gen(j => s"T$j")(", ") + val params = (1 to i).gen(j => s"$mtype<${parameterInset}T$j> ts$j")(", ") xs""" /$javadoc * Creates a {@code For}-comprehension of ${i.numerus(mtype)}. ${(0 to i).gen(j => if (j == 0) "*" else s"* @param ts$j the ${j.ordinal} $mtype")("\n")} + ${if (isComplex) s"* @param left-hand type of all ${mtype}s\n" else ""} ${(1 to i).gen(j => s"* @param component type of the ${j.ordinal} $mtype")("\n")} * @return a new {@code For}-comprehension of arity $i */ @@ -792,7 +796,8 @@ def generateMainClasses(): Unit = { val rtype = if (mtype == "Iterable") { IteratorType } else { mtype } val cons: String => String = if (mtype == "Iterable") { m => s"$IteratorType.ofAll($m)" } else { m => m } val forClassName = if (mtype == "Iterable") { s"For$i" } else { s"For$i$mtype" } - val generics = (1 to i).gen(j => s"T$j")(", ") + val parameterInset = (if (monadicTypesThatNeedParameter.contains(mtype)) { "L, " } else "") + val generics = parameterInset + (1 to i).gen(j => s"T$j")(", ") val functionType = i match { case 1 => FunctionType case 2 => BiFunctionType @@ -805,20 +810,20 @@ def generateMainClasses(): Unit = { */ public static class $forClassName<$generics> { - ${(1 to i).gen(j => xs"""private final $mtype ts$j;""")("\n")} + ${(1 to i).gen(j => xs"""private final $mtype<${parameterInset}T$j> ts$j;""")("\n")} - private $forClassName(${(1 to i).gen(j => s"$mtype ts$j")(", ")}) { + private $forClassName(${(1 to i).gen(j => s"$mtype<${parameterInset}T$j> ts$j")(", ")}) { ${(1 to i).gen(j => xs"""this.ts$j = ts$j;""")("\n")} } /$javadoc - * Yields a result for elements of the cross product of the underlying ${i.plural(mtype)}. + * Yields a result for elements of the cross-product of the underlying ${i.plural(mtype)}. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code $rtype} elements * @return an {@code $rtype} of mapped results */ - public $rtype yield($functionType<$args, ? extends R> f) { + public $rtype<${parameterInset}R> yield($functionType<$args, ? extends R> f) { $Objects.requireNonNull(f, "f is null"); ${if (i == 1) xs""" return ${cons("ts1")}.map(f); @@ -835,7 +840,7 @@ def generateMainClasses(): Unit = { * * @return an {@code Iterator} of mapped results */ - public $rtype yield() { + public $rtype<${parameterInset}T1> yield() { return this.yield(Function.identity()); } """)} @@ -2657,13 +2662,20 @@ def generateTestClasses(): Unit = { val SeqType = im.getType("io.vavr.collection.Seq") val MapType = im.getType("io.vavr.collection.Map") val OptionType = im.getType("io.vavr.control.Option") + val EitherType = im.getType("io.vavr.control.Either") + val ValidationType = im.getType("io.vavr.control.Validation") val FutureType = im.getType("io.vavr.concurrent.Future") val ExecutorsType = im.getType("java.util.concurrent.Executors") val ExecutorService = s"$ExecutorsType.newSingleThreadExecutor()" val TryType = im.getType("io.vavr.control.Try") val JavaComparatorType = im.getType("java.util.Comparator") - val monadicTypesFor = List(OptionType) + val monadicTypesFor = List(OptionType, EitherType, ValidationType) + val monadicTypeMetadataFor = Map( + (OptionType -> ("", "of")), + (EitherType -> ("Object, ", "right")), + (ValidationType -> ("Object, ", "valid")) + ) val monadicFunctionTypesFor = List(FutureType, TryType) val d = "$" @@ -2952,11 +2964,14 @@ def generateTestClasses(): Unit = { } """)("\n\n")} - ${monadicTypesFor.gen(mtype => (1 to N).gen(i => { xs""" + ${monadicTypesFor.gen(mtype => (1 to N).gen(i => + val (parameterInset, builderName) = monadicTypeMetadataFor(mtype); + { xs""" + @$test public void shouldIterateFor$mtype$i() { - final $mtype result = For( - ${(1 to i).gen(j => s"$mtype.of($j)")(",\n")} + final $mtype<${parameterInset}Integer> result = For( + ${(1 to i).gen(j => s"$mtype.${builderName}($j)")(",\n")} ).yield(${(i > 1).gen("(")}${(1 to i).gen(j => s"i$j")(", ")}${(i > 1).gen(")")} -> ${(1 to i).gen(j => s"i$j")(" + ")}); $assertThat(result.get()).isEqualTo(${(1 to i).sum}); } diff --git a/vavr/src-gen/main/java/io/vavr/API.java b/vavr/src-gen/main/java/io/vavr/API.java index 0938887ea..99c8a182b 100644 --- a/vavr/src-gen/main/java/io/vavr/API.java +++ b/vavr/src-gen/main/java/io/vavr/API.java @@ -2335,6 +2335,7 @@ public static Iterator For(Iterable ts, Function component type of the 1st Iterable * @return a new {@code For}-comprehension of arity 1 */ @@ -2348,6 +2349,7 @@ public static For1 For(Iterable ts1) { * * @param ts1 the 1st Iterable * @param ts2 the 2nd Iterable + * @param component type of the 1st Iterable * @param component type of the 2nd Iterable * @return a new {@code For}-comprehension of arity 2 @@ -2364,6 +2366,7 @@ public static For2 For(Iterable ts1, Iterable ts2) { * @param ts1 the 1st Iterable * @param ts2 the 2nd Iterable * @param ts3 the 3rd Iterable + * @param component type of the 1st Iterable * @param component type of the 2nd Iterable * @param component type of the 3rd Iterable @@ -2383,6 +2386,7 @@ public static For3 For(Iterable ts1, Iterable t * @param ts2 the 2nd Iterable * @param ts3 the 3rd Iterable * @param ts4 the 4th Iterable + * @param component type of the 1st Iterable * @param component type of the 2nd Iterable * @param component type of the 3rd Iterable @@ -2405,6 +2409,7 @@ public static For4 For(Iterable ts1, Iterab * @param ts3 the 3rd Iterable * @param ts4 the 4th Iterable * @param ts5 the 5th Iterable + * @param component type of the 1st Iterable * @param component type of the 2nd Iterable * @param component type of the 3rd Iterable @@ -2430,6 +2435,7 @@ public static For5 For(Iterable ts1 * @param ts4 the 4th Iterable * @param ts5 the 5th Iterable * @param ts6 the 6th Iterable + * @param component type of the 1st Iterable * @param component type of the 2nd Iterable * @param component type of the 3rd Iterable @@ -2458,6 +2464,7 @@ public static For6 For(Iterable * @param ts5 the 5th Iterable * @param ts6 the 6th Iterable * @param ts7 the 7th Iterable + * @param component type of the 1st Iterable * @param component type of the 2nd Iterable * @param component type of the 3rd Iterable @@ -2489,6 +2496,7 @@ public static For7 For( * @param ts6 the 6th Iterable * @param ts7 the 7th Iterable * @param ts8 the 8th Iterable + * @param component type of the 1st Iterable * @param component type of the 2nd Iterable * @param component type of the 3rd Iterable @@ -2515,6 +2523,7 @@ public static For8 component type of the 1st Option * @return a new {@code For}-comprehension of arity 1 */ @@ -2528,6 +2537,7 @@ public static For1Option For(Option ts1) { * * @param ts1 the 1st Option * @param ts2 the 2nd Option + * @param component type of the 1st Option * @param component type of the 2nd Option * @return a new {@code For}-comprehension of arity 2 @@ -2544,6 +2554,7 @@ public static For2Option For(Option ts1, Option ts2) { * @param ts1 the 1st Option * @param ts2 the 2nd Option * @param ts3 the 3rd Option + * @param component type of the 1st Option * @param component type of the 2nd Option * @param component type of the 3rd Option @@ -2563,6 +2574,7 @@ public static For3Option For(Option ts1, Option * @param ts2 the 2nd Option * @param ts3 the 3rd Option * @param ts4 the 4th Option + * @param component type of the 1st Option * @param component type of the 2nd Option * @param component type of the 3rd Option @@ -2585,6 +2597,7 @@ public static For4Option For(Option ts1, Op * @param ts3 the 3rd Option * @param ts4 the 4th Option * @param ts5 the 5th Option + * @param component type of the 1st Option * @param component type of the 2nd Option * @param component type of the 3rd Option @@ -2610,6 +2623,7 @@ public static For5Option For(Option * @param ts4 the 4th Option * @param ts5 the 5th Option * @param ts6 the 6th Option + * @param component type of the 1st Option * @param component type of the 2nd Option * @param component type of the 3rd Option @@ -2638,6 +2652,7 @@ public static For6Option For(Op * @param ts5 the 5th Option * @param ts6 the 6th Option * @param ts7 the 7th Option + * @param component type of the 1st Option * @param component type of the 2nd Option * @param component type of the 3rd Option @@ -2669,6 +2684,7 @@ public static For7Option component type of the 1st Option * @param component type of the 2nd Option * @param component type of the 3rd Option @@ -2695,6 +2711,7 @@ public static For8Option component type of the 1st Future * @return a new {@code For}-comprehension of arity 1 */ @@ -2708,6 +2725,7 @@ public static For1Future For(Future ts1) { * * @param ts1 the 1st Future * @param ts2 the 2nd Future + * @param component type of the 1st Future * @param component type of the 2nd Future * @return a new {@code For}-comprehension of arity 2 @@ -2724,6 +2742,7 @@ public static For2Future For(Future ts1, Future ts2) { * @param ts1 the 1st Future * @param ts2 the 2nd Future * @param ts3 the 3rd Future + * @param component type of the 1st Future * @param component type of the 2nd Future * @param component type of the 3rd Future @@ -2743,6 +2762,7 @@ public static For3Future For(Future ts1, Future * @param ts2 the 2nd Future * @param ts3 the 3rd Future * @param ts4 the 4th Future + * @param component type of the 1st Future * @param component type of the 2nd Future * @param component type of the 3rd Future @@ -2765,6 +2785,7 @@ public static For4Future For(Future ts1, Fu * @param ts3 the 3rd Future * @param ts4 the 4th Future * @param ts5 the 5th Future + * @param component type of the 1st Future * @param component type of the 2nd Future * @param component type of the 3rd Future @@ -2790,6 +2811,7 @@ public static For5Future For(Future * @param ts4 the 4th Future * @param ts5 the 5th Future * @param ts6 the 6th Future + * @param component type of the 1st Future * @param component type of the 2nd Future * @param component type of the 3rd Future @@ -2818,6 +2840,7 @@ public static For6Future For(Fu * @param ts5 the 5th Future * @param ts6 the 6th Future * @param ts7 the 7th Future + * @param component type of the 1st Future * @param component type of the 2nd Future * @param component type of the 3rd Future @@ -2849,6 +2872,7 @@ public static For7Future component type of the 1st Future * @param component type of the 2nd Future * @param component type of the 3rd Future @@ -2875,6 +2899,7 @@ public static For8Future component type of the 1st Try * @return a new {@code For}-comprehension of arity 1 */ @@ -2888,6 +2913,7 @@ public static For1Try For(Try ts1) { * * @param ts1 the 1st Try * @param ts2 the 2nd Try + * @param component type of the 1st Try * @param component type of the 2nd Try * @return a new {@code For}-comprehension of arity 2 @@ -2904,6 +2930,7 @@ public static For2Try For(Try ts1, Try ts2) { * @param ts1 the 1st Try * @param ts2 the 2nd Try * @param ts3 the 3rd Try + * @param component type of the 1st Try * @param component type of the 2nd Try * @param component type of the 3rd Try @@ -2923,6 +2950,7 @@ public static For3Try For(Try ts1, Try ts2, Try * @param ts2 the 2nd Try * @param ts3 the 3rd Try * @param ts4 the 4th Try + * @param component type of the 1st Try * @param component type of the 2nd Try * @param component type of the 3rd Try @@ -2945,6 +2973,7 @@ public static For4Try For(Try ts1, Try * @param ts3 the 3rd Try * @param ts4 the 4th Try * @param ts5 the 5th Try + * @param component type of the 1st Try * @param component type of the 2nd Try * @param component type of the 3rd Try @@ -2970,6 +2999,7 @@ public static For5Try For(Try ts1, * @param ts4 the 4th Try * @param ts5 the 5th Try * @param ts6 the 6th Try + * @param component type of the 1st Try * @param component type of the 2nd Try * @param component type of the 3rd Try @@ -2998,6 +3028,7 @@ public static For6Try For(Try component type of the 1st Try * @param component type of the 2nd Try * @param component type of the 3rd Try @@ -3029,6 +3060,7 @@ public static For7Try F * @param ts6 the 6th Try * @param ts7 the 7th Try * @param ts8 the 8th Try + * @param component type of the 1st Try * @param component type of the 2nd Try * @param component type of the 3rd Try @@ -3055,6 +3087,7 @@ public static For8Try component type of the 1st List * @return a new {@code For}-comprehension of arity 1 */ @@ -3068,6 +3101,7 @@ public static For1List For(List ts1) { * * @param ts1 the 1st List * @param ts2 the 2nd List + * @param component type of the 1st List * @param component type of the 2nd List * @return a new {@code For}-comprehension of arity 2 @@ -3084,6 +3118,7 @@ public static For2List For(List ts1, List ts2) { * @param ts1 the 1st List * @param ts2 the 2nd List * @param ts3 the 3rd List + * @param component type of the 1st List * @param component type of the 2nd List * @param component type of the 3rd List @@ -3103,6 +3138,7 @@ public static For3List For(List ts1, List ts2, * @param ts2 the 2nd List * @param ts3 the 3rd List * @param ts4 the 4th List + * @param component type of the 1st List * @param component type of the 2nd List * @param component type of the 3rd List @@ -3125,6 +3161,7 @@ public static For4List For(List ts1, List component type of the 1st List * @param component type of the 2nd List * @param component type of the 3rd List @@ -3150,6 +3187,7 @@ public static For5List For(List ts1 * @param ts4 the 4th List * @param ts5 the 5th List * @param ts6 the 6th List + * @param component type of the 1st List * @param component type of the 2nd List * @param component type of the 3rd List @@ -3178,6 +3216,7 @@ public static For6List For(List * @param ts5 the 5th List * @param ts6 the 6th List * @param ts7 the 7th List + * @param component type of the 1st List * @param component type of the 2nd List * @param component type of the 3rd List @@ -3209,6 +3248,7 @@ public static For7List * @param ts6 the 6th List * @param ts7 the 7th List * @param ts8 the 8th List + * @param component type of the 1st List * @param component type of the 2nd List * @param component type of the 3rd List @@ -3231,6 +3271,382 @@ public static For8List(ts1, ts2, ts3, ts4, ts5, ts6, ts7, ts8); } + /** + * Creates a {@code For}-comprehension of one Either. + * + * @param ts1 the 1st Either + * @param left-hand type of all Eithers + * @param component type of the 1st Either + * @return a new {@code For}-comprehension of arity 1 + */ + public static For1Either For(Either ts1) { + Objects.requireNonNull(ts1, "ts1 is null"); + return new For1Either<>(ts1); + } + + /** + * Creates a {@code For}-comprehension of two Eithers. + * + * @param ts1 the 1st Either + * @param ts2 the 2nd Either + * @param left-hand type of all Eithers + * @param component type of the 1st Either + * @param component type of the 2nd Either + * @return a new {@code For}-comprehension of arity 2 + */ + public static For2Either For(Either ts1, Either ts2) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + return new For2Either<>(ts1, ts2); + } + + /** + * Creates a {@code For}-comprehension of three Eithers. + * + * @param ts1 the 1st Either + * @param ts2 the 2nd Either + * @param ts3 the 3rd Either + * @param left-hand type of all Eithers + * @param component type of the 1st Either + * @param component type of the 2nd Either + * @param component type of the 3rd Either + * @return a new {@code For}-comprehension of arity 3 + */ + public static For3Either For(Either ts1, Either ts2, Either ts3) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + return new For3Either<>(ts1, ts2, ts3); + } + + /** + * Creates a {@code For}-comprehension of 4 Eithers. + * + * @param ts1 the 1st Either + * @param ts2 the 2nd Either + * @param ts3 the 3rd Either + * @param ts4 the 4th Either + * @param left-hand type of all Eithers + * @param component type of the 1st Either + * @param component type of the 2nd Either + * @param component type of the 3rd Either + * @param component type of the 4th Either + * @return a new {@code For}-comprehension of arity 4 + */ + public static For4Either For(Either ts1, Either ts2, Either ts3, Either ts4) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + Objects.requireNonNull(ts4, "ts4 is null"); + return new For4Either<>(ts1, ts2, ts3, ts4); + } + + /** + * Creates a {@code For}-comprehension of 5 Eithers. + * + * @param ts1 the 1st Either + * @param ts2 the 2nd Either + * @param ts3 the 3rd Either + * @param ts4 the 4th Either + * @param ts5 the 5th Either + * @param left-hand type of all Eithers + * @param component type of the 1st Either + * @param component type of the 2nd Either + * @param component type of the 3rd Either + * @param component type of the 4th Either + * @param component type of the 5th Either + * @return a new {@code For}-comprehension of arity 5 + */ + public static For5Either For(Either ts1, Either ts2, Either ts3, Either ts4, Either ts5) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + Objects.requireNonNull(ts4, "ts4 is null"); + Objects.requireNonNull(ts5, "ts5 is null"); + return new For5Either<>(ts1, ts2, ts3, ts4, ts5); + } + + /** + * Creates a {@code For}-comprehension of 6 Eithers. + * + * @param ts1 the 1st Either + * @param ts2 the 2nd Either + * @param ts3 the 3rd Either + * @param ts4 the 4th Either + * @param ts5 the 5th Either + * @param ts6 the 6th Either + * @param left-hand type of all Eithers + * @param component type of the 1st Either + * @param component type of the 2nd Either + * @param component type of the 3rd Either + * @param component type of the 4th Either + * @param component type of the 5th Either + * @param component type of the 6th Either + * @return a new {@code For}-comprehension of arity 6 + */ + public static For6Either For(Either ts1, Either ts2, Either ts3, Either ts4, Either ts5, Either ts6) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + Objects.requireNonNull(ts4, "ts4 is null"); + Objects.requireNonNull(ts5, "ts5 is null"); + Objects.requireNonNull(ts6, "ts6 is null"); + return new For6Either<>(ts1, ts2, ts3, ts4, ts5, ts6); + } + + /** + * Creates a {@code For}-comprehension of 7 Eithers. + * + * @param ts1 the 1st Either + * @param ts2 the 2nd Either + * @param ts3 the 3rd Either + * @param ts4 the 4th Either + * @param ts5 the 5th Either + * @param ts6 the 6th Either + * @param ts7 the 7th Either + * @param left-hand type of all Eithers + * @param component type of the 1st Either + * @param component type of the 2nd Either + * @param component type of the 3rd Either + * @param component type of the 4th Either + * @param component type of the 5th Either + * @param component type of the 6th Either + * @param component type of the 7th Either + * @return a new {@code For}-comprehension of arity 7 + */ + public static For7Either For(Either ts1, Either ts2, Either ts3, Either ts4, Either ts5, Either ts6, Either ts7) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + Objects.requireNonNull(ts4, "ts4 is null"); + Objects.requireNonNull(ts5, "ts5 is null"); + Objects.requireNonNull(ts6, "ts6 is null"); + Objects.requireNonNull(ts7, "ts7 is null"); + return new For7Either<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7); + } + + /** + * Creates a {@code For}-comprehension of 8 Eithers. + * + * @param ts1 the 1st Either + * @param ts2 the 2nd Either + * @param ts3 the 3rd Either + * @param ts4 the 4th Either + * @param ts5 the 5th Either + * @param ts6 the 6th Either + * @param ts7 the 7th Either + * @param ts8 the 8th Either + * @param left-hand type of all Eithers + * @param component type of the 1st Either + * @param component type of the 2nd Either + * @param component type of the 3rd Either + * @param component type of the 4th Either + * @param component type of the 5th Either + * @param component type of the 6th Either + * @param component type of the 7th Either + * @param component type of the 8th Either + * @return a new {@code For}-comprehension of arity 8 + */ + public static For8Either For(Either ts1, Either ts2, Either ts3, Either ts4, Either ts5, Either ts6, Either ts7, Either ts8) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + Objects.requireNonNull(ts4, "ts4 is null"); + Objects.requireNonNull(ts5, "ts5 is null"); + Objects.requireNonNull(ts6, "ts6 is null"); + Objects.requireNonNull(ts7, "ts7 is null"); + Objects.requireNonNull(ts8, "ts8 is null"); + return new For8Either<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7, ts8); + } + + /** + * Creates a {@code For}-comprehension of one Validation. + * + * @param ts1 the 1st Validation + * @param left-hand type of all Validations + * @param component type of the 1st Validation + * @return a new {@code For}-comprehension of arity 1 + */ + public static For1Validation For(Validation ts1) { + Objects.requireNonNull(ts1, "ts1 is null"); + return new For1Validation<>(ts1); + } + + /** + * Creates a {@code For}-comprehension of two Validations. + * + * @param ts1 the 1st Validation + * @param ts2 the 2nd Validation + * @param left-hand type of all Validations + * @param component type of the 1st Validation + * @param component type of the 2nd Validation + * @return a new {@code For}-comprehension of arity 2 + */ + public static For2Validation For(Validation ts1, Validation ts2) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + return new For2Validation<>(ts1, ts2); + } + + /** + * Creates a {@code For}-comprehension of three Validations. + * + * @param ts1 the 1st Validation + * @param ts2 the 2nd Validation + * @param ts3 the 3rd Validation + * @param left-hand type of all Validations + * @param component type of the 1st Validation + * @param component type of the 2nd Validation + * @param component type of the 3rd Validation + * @return a new {@code For}-comprehension of arity 3 + */ + public static For3Validation For(Validation ts1, Validation ts2, Validation ts3) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + return new For3Validation<>(ts1, ts2, ts3); + } + + /** + * Creates a {@code For}-comprehension of 4 Validations. + * + * @param ts1 the 1st Validation + * @param ts2 the 2nd Validation + * @param ts3 the 3rd Validation + * @param ts4 the 4th Validation + * @param left-hand type of all Validations + * @param component type of the 1st Validation + * @param component type of the 2nd Validation + * @param component type of the 3rd Validation + * @param component type of the 4th Validation + * @return a new {@code For}-comprehension of arity 4 + */ + public static For4Validation For(Validation ts1, Validation ts2, Validation ts3, Validation ts4) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + Objects.requireNonNull(ts4, "ts4 is null"); + return new For4Validation<>(ts1, ts2, ts3, ts4); + } + + /** + * Creates a {@code For}-comprehension of 5 Validations. + * + * @param ts1 the 1st Validation + * @param ts2 the 2nd Validation + * @param ts3 the 3rd Validation + * @param ts4 the 4th Validation + * @param ts5 the 5th Validation + * @param left-hand type of all Validations + * @param component type of the 1st Validation + * @param component type of the 2nd Validation + * @param component type of the 3rd Validation + * @param component type of the 4th Validation + * @param component type of the 5th Validation + * @return a new {@code For}-comprehension of arity 5 + */ + public static For5Validation For(Validation ts1, Validation ts2, Validation ts3, Validation ts4, Validation ts5) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + Objects.requireNonNull(ts4, "ts4 is null"); + Objects.requireNonNull(ts5, "ts5 is null"); + return new For5Validation<>(ts1, ts2, ts3, ts4, ts5); + } + + /** + * Creates a {@code For}-comprehension of 6 Validations. + * + * @param ts1 the 1st Validation + * @param ts2 the 2nd Validation + * @param ts3 the 3rd Validation + * @param ts4 the 4th Validation + * @param ts5 the 5th Validation + * @param ts6 the 6th Validation + * @param left-hand type of all Validations + * @param component type of the 1st Validation + * @param component type of the 2nd Validation + * @param component type of the 3rd Validation + * @param component type of the 4th Validation + * @param component type of the 5th Validation + * @param component type of the 6th Validation + * @return a new {@code For}-comprehension of arity 6 + */ + public static For6Validation For(Validation ts1, Validation ts2, Validation ts3, Validation ts4, Validation ts5, Validation ts6) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + Objects.requireNonNull(ts4, "ts4 is null"); + Objects.requireNonNull(ts5, "ts5 is null"); + Objects.requireNonNull(ts6, "ts6 is null"); + return new For6Validation<>(ts1, ts2, ts3, ts4, ts5, ts6); + } + + /** + * Creates a {@code For}-comprehension of 7 Validations. + * + * @param ts1 the 1st Validation + * @param ts2 the 2nd Validation + * @param ts3 the 3rd Validation + * @param ts4 the 4th Validation + * @param ts5 the 5th Validation + * @param ts6 the 6th Validation + * @param ts7 the 7th Validation + * @param left-hand type of all Validations + * @param component type of the 1st Validation + * @param component type of the 2nd Validation + * @param component type of the 3rd Validation + * @param component type of the 4th Validation + * @param component type of the 5th Validation + * @param component type of the 6th Validation + * @param component type of the 7th Validation + * @return a new {@code For}-comprehension of arity 7 + */ + public static For7Validation For(Validation ts1, Validation ts2, Validation ts3, Validation ts4, Validation ts5, Validation ts6, Validation ts7) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + Objects.requireNonNull(ts4, "ts4 is null"); + Objects.requireNonNull(ts5, "ts5 is null"); + Objects.requireNonNull(ts6, "ts6 is null"); + Objects.requireNonNull(ts7, "ts7 is null"); + return new For7Validation<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7); + } + + /** + * Creates a {@code For}-comprehension of 8 Validations. + * + * @param ts1 the 1st Validation + * @param ts2 the 2nd Validation + * @param ts3 the 3rd Validation + * @param ts4 the 4th Validation + * @param ts5 the 5th Validation + * @param ts6 the 6th Validation + * @param ts7 the 7th Validation + * @param ts8 the 8th Validation + * @param left-hand type of all Validations + * @param component type of the 1st Validation + * @param component type of the 2nd Validation + * @param component type of the 3rd Validation + * @param component type of the 4th Validation + * @param component type of the 5th Validation + * @param component type of the 6th Validation + * @param component type of the 7th Validation + * @param component type of the 8th Validation + * @return a new {@code For}-comprehension of arity 8 + */ + public static For8Validation For(Validation ts1, Validation ts2, Validation ts3, Validation ts4, Validation ts5, Validation ts6, Validation ts7, Validation ts8) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + Objects.requireNonNull(ts4, "ts4 is null"); + Objects.requireNonNull(ts5, "ts5 is null"); + Objects.requireNonNull(ts6, "ts6 is null"); + Objects.requireNonNull(ts7, "ts7 is null"); + Objects.requireNonNull(ts8, "ts8 is null"); + return new For8Validation<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7, ts8); + } + /** * For-comprehension with one Iterable. */ @@ -3243,9 +3659,9 @@ private For1(Iterable ts1) { } /** - * Yields a result for elements of the cross product of the underlying Iterable. + * Yields a result for elements of the cross-product of the underlying Iterable. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Iterator} elements * @return an {@code Iterator} of mapped results */ @@ -3278,9 +3694,9 @@ private For2(Iterable ts1, Iterable ts2) { } /** - * Yields a result for elements of the cross product of the underlying Iterables. + * Yields a result for elements of the cross-product of the underlying Iterables. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Iterator} elements * @return an {@code Iterator} of mapped results */ @@ -3309,9 +3725,9 @@ private For3(Iterable ts1, Iterable ts2, Iterable ts3) { } /** - * Yields a result for elements of the cross product of the underlying Iterables. + * Yields a result for elements of the cross-product of the underlying Iterables. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Iterator} elements * @return an {@code Iterator} of mapped results */ @@ -3343,9 +3759,9 @@ private For4(Iterable ts1, Iterable ts2, Iterable ts3, Iterable } /** - * Yields a result for elements of the cross product of the underlying Iterables. + * Yields a result for elements of the cross-product of the underlying Iterables. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Iterator} elements * @return an {@code Iterator} of mapped results */ @@ -3380,9 +3796,9 @@ private For5(Iterable ts1, Iterable ts2, Iterable ts3, Iterable } /** - * Yields a result for elements of the cross product of the underlying Iterables. + * Yields a result for elements of the cross-product of the underlying Iterables. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Iterator} elements * @return an {@code Iterator} of mapped results */ @@ -3420,9 +3836,9 @@ private For6(Iterable ts1, Iterable ts2, Iterable ts3, Iterable } /** - * Yields a result for elements of the cross product of the underlying Iterables. + * Yields a result for elements of the cross-product of the underlying Iterables. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Iterator} elements * @return an {@code Iterator} of mapped results */ @@ -3463,9 +3879,9 @@ private For7(Iterable ts1, Iterable ts2, Iterable ts3, Iterable } /** - * Yields a result for elements of the cross product of the underlying Iterables. + * Yields a result for elements of the cross-product of the underlying Iterables. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Iterator} elements * @return an {@code Iterator} of mapped results */ @@ -3509,9 +3925,9 @@ private For8(Iterable ts1, Iterable ts2, Iterable ts3, Iterable } /** - * Yields a result for elements of the cross product of the underlying Iterables. + * Yields a result for elements of the cross-product of the underlying Iterables. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Iterator} elements * @return an {@code Iterator} of mapped results */ @@ -3542,9 +3958,9 @@ private For1Option(Option ts1) { } /** - * Yields a result for elements of the cross product of the underlying Option. + * Yields a result for elements of the cross-product of the underlying Option. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Option} elements * @return an {@code Option} of mapped results */ @@ -3577,9 +3993,9 @@ private For2Option(Option ts1, Option ts2) { } /** - * Yields a result for elements of the cross product of the underlying Options. + * Yields a result for elements of the cross-product of the underlying Options. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Option} elements * @return an {@code Option} of mapped results */ @@ -3608,9 +4024,9 @@ private For3Option(Option ts1, Option ts2, Option ts3) { } /** - * Yields a result for elements of the cross product of the underlying Options. + * Yields a result for elements of the cross-product of the underlying Options. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Option} elements * @return an {@code Option} of mapped results */ @@ -3642,9 +4058,9 @@ private For4Option(Option ts1, Option ts2, Option ts3, Option ts } /** - * Yields a result for elements of the cross product of the underlying Options. + * Yields a result for elements of the cross-product of the underlying Options. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Option} elements * @return an {@code Option} of mapped results */ @@ -3679,9 +4095,9 @@ private For5Option(Option ts1, Option ts2, Option ts3, Option ts } /** - * Yields a result for elements of the cross product of the underlying Options. + * Yields a result for elements of the cross-product of the underlying Options. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Option} elements * @return an {@code Option} of mapped results */ @@ -3719,9 +4135,9 @@ private For6Option(Option ts1, Option ts2, Option ts3, Option ts } /** - * Yields a result for elements of the cross product of the underlying Options. + * Yields a result for elements of the cross-product of the underlying Options. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Option} elements * @return an {@code Option} of mapped results */ @@ -3762,9 +4178,9 @@ private For7Option(Option ts1, Option ts2, Option ts3, Option ts } /** - * Yields a result for elements of the cross product of the underlying Options. + * Yields a result for elements of the cross-product of the underlying Options. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Option} elements * @return an {@code Option} of mapped results */ @@ -3808,9 +4224,9 @@ private For8Option(Option ts1, Option ts2, Option ts3, Option ts } /** - * Yields a result for elements of the cross product of the underlying Options. + * Yields a result for elements of the cross-product of the underlying Options. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Option} elements * @return an {@code Option} of mapped results */ @@ -3841,9 +4257,9 @@ private For1Future(Future ts1) { } /** - * Yields a result for elements of the cross product of the underlying Future. + * Yields a result for elements of the cross-product of the underlying Future. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Future} elements * @return an {@code Future} of mapped results */ @@ -3876,9 +4292,9 @@ private For2Future(Future ts1, Future ts2) { } /** - * Yields a result for elements of the cross product of the underlying Futures. + * Yields a result for elements of the cross-product of the underlying Futures. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Future} elements * @return an {@code Future} of mapped results */ @@ -3907,9 +4323,9 @@ private For3Future(Future ts1, Future ts2, Future ts3) { } /** - * Yields a result for elements of the cross product of the underlying Futures. + * Yields a result for elements of the cross-product of the underlying Futures. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Future} elements * @return an {@code Future} of mapped results */ @@ -3941,9 +4357,9 @@ private For4Future(Future ts1, Future ts2, Future ts3, Future ts } /** - * Yields a result for elements of the cross product of the underlying Futures. + * Yields a result for elements of the cross-product of the underlying Futures. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Future} elements * @return an {@code Future} of mapped results */ @@ -3978,9 +4394,9 @@ private For5Future(Future ts1, Future ts2, Future ts3, Future ts } /** - * Yields a result for elements of the cross product of the underlying Futures. + * Yields a result for elements of the cross-product of the underlying Futures. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Future} elements * @return an {@code Future} of mapped results */ @@ -4018,9 +4434,9 @@ private For6Future(Future ts1, Future ts2, Future ts3, Future ts } /** - * Yields a result for elements of the cross product of the underlying Futures. + * Yields a result for elements of the cross-product of the underlying Futures. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Future} elements * @return an {@code Future} of mapped results */ @@ -4061,9 +4477,9 @@ private For7Future(Future ts1, Future ts2, Future ts3, Future ts } /** - * Yields a result for elements of the cross product of the underlying Futures. + * Yields a result for elements of the cross-product of the underlying Futures. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Future} elements * @return an {@code Future} of mapped results */ @@ -4107,9 +4523,9 @@ private For8Future(Future ts1, Future ts2, Future ts3, Future ts } /** - * Yields a result for elements of the cross product of the underlying Futures. + * Yields a result for elements of the cross-product of the underlying Futures. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Future} elements * @return an {@code Future} of mapped results */ @@ -4140,9 +4556,9 @@ private For1Try(Try ts1) { } /** - * Yields a result for elements of the cross product of the underlying Try. + * Yields a result for elements of the cross-product of the underlying Try. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Try} elements * @return an {@code Try} of mapped results */ @@ -4175,9 +4591,9 @@ private For2Try(Try ts1, Try ts2) { } /** - * Yields a result for elements of the cross product of the underlying Trys. + * Yields a result for elements of the cross-product of the underlying Trys. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Try} elements * @return an {@code Try} of mapped results */ @@ -4206,9 +4622,9 @@ private For3Try(Try ts1, Try ts2, Try ts3) { } /** - * Yields a result for elements of the cross product of the underlying Trys. + * Yields a result for elements of the cross-product of the underlying Trys. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Try} elements * @return an {@code Try} of mapped results */ @@ -4240,9 +4656,9 @@ private For4Try(Try ts1, Try ts2, Try ts3, Try ts4) { } /** - * Yields a result for elements of the cross product of the underlying Trys. + * Yields a result for elements of the cross-product of the underlying Trys. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Try} elements * @return an {@code Try} of mapped results */ @@ -4277,9 +4693,9 @@ private For5Try(Try ts1, Try ts2, Try ts3, Try ts4, Try ts5) } /** - * Yields a result for elements of the cross product of the underlying Trys. + * Yields a result for elements of the cross-product of the underlying Trys. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Try} elements * @return an {@code Try} of mapped results */ @@ -4317,9 +4733,9 @@ private For6Try(Try ts1, Try ts2, Try ts3, Try ts4, Try ts5, } /** - * Yields a result for elements of the cross product of the underlying Trys. + * Yields a result for elements of the cross-product of the underlying Trys. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Try} elements * @return an {@code Try} of mapped results */ @@ -4360,9 +4776,9 @@ private For7Try(Try ts1, Try ts2, Try ts3, Try ts4, Try ts5, } /** - * Yields a result for elements of the cross product of the underlying Trys. + * Yields a result for elements of the cross-product of the underlying Trys. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Try} elements * @return an {@code Try} of mapped results */ @@ -4406,9 +4822,9 @@ private For8Try(Try ts1, Try ts2, Try ts3, Try ts4, Try ts5, } /** - * Yields a result for elements of the cross product of the underlying Trys. + * Yields a result for elements of the cross-product of the underlying Trys. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code Try} elements * @return an {@code Try} of mapped results */ @@ -4439,9 +4855,9 @@ private For1List(List ts1) { } /** - * Yields a result for elements of the cross product of the underlying List. + * Yields a result for elements of the cross-product of the underlying List. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code List} elements * @return an {@code List} of mapped results */ @@ -4474,9 +4890,9 @@ private For2List(List ts1, List ts2) { } /** - * Yields a result for elements of the cross product of the underlying Lists. + * Yields a result for elements of the cross-product of the underlying Lists. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code List} elements * @return an {@code List} of mapped results */ @@ -4505,9 +4921,9 @@ private For3List(List ts1, List ts2, List ts3) { } /** - * Yields a result for elements of the cross product of the underlying Lists. + * Yields a result for elements of the cross-product of the underlying Lists. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code List} elements * @return an {@code List} of mapped results */ @@ -4539,9 +4955,9 @@ private For4List(List ts1, List ts2, List ts3, List ts4) { } /** - * Yields a result for elements of the cross product of the underlying Lists. + * Yields a result for elements of the cross-product of the underlying Lists. * - * @param f a function that maps an element of the cross product to a result + * @param f a function that maps an element of the cross-product to a result * @param type of the resulting {@code List} elements * @return an {@code List} of mapped results */ @@ -4576,9 +4992,9 @@ private For5List(List ts1, List ts2, List ts3, List ts4, List type of the resulting {@code List} elements * @return an {@code List} of mapped results */ @@ -4616,9 +5032,9 @@ private For6List(List ts1, List ts2, List ts3, List ts4, List type of the resulting {@code List} elements * @return an {@code List} of mapped results */ @@ -4659,9 +5075,9 @@ private For7List(List ts1, List ts2, List ts3, List ts4, List type of the resulting {@code List} elements * @return an {@code List} of mapped results */ @@ -4705,9 +5121,9 @@ private For8List(List ts1, List ts2, List ts3, List ts4, List type of the resulting {@code List} elements * @return an {@code List} of mapped results */ @@ -4726,6 +5142,604 @@ public List yield(Function8 { + + private final Either ts1; + + private For1Either(Either ts1) { + this.ts1 = ts1; + } + + /** + * Yields a result for elements of the cross-product of the underlying Either. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Either} elements + * @return an {@code Either} of mapped results + */ + public Either yield(Function f) { + Objects.requireNonNull(f, "f is null"); + return ts1.map(f); + } + + /** + * A shortcut for {@code yield(Function.identity())}. + * + * @return an {@code Iterator} of mapped results + */ + public Either yield() { + return this.yield(Function.identity()); + } + } + + /** + * For-comprehension with two Eithers. + */ + public static class For2Either { + + private final Either ts1; + private final Either ts2; + + private For2Either(Either ts1, Either ts2) { + this.ts1 = ts1; + this.ts2 = ts2; + } + + /** + * Yields a result for elements of the cross-product of the underlying Eithers. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Either} elements + * @return an {@code Either} of mapped results + */ + public Either yield(BiFunction f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.map(t2 -> f.apply(t1, t2))); + } + + } + + /** + * For-comprehension with three Eithers. + */ + public static class For3Either { + + private final Either ts1; + private final Either ts2; + private final Either ts3; + + private For3Either(Either ts1, Either ts2, Either ts3) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + } + + /** + * Yields a result for elements of the cross-product of the underlying Eithers. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Either} elements + * @return an {@code Either} of mapped results + */ + public Either yield(Function3 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.map(t3 -> f.apply(t1, t2, t3)))); + } + + } + + /** + * For-comprehension with 4 Eithers. + */ + public static class For4Either { + + private final Either ts1; + private final Either ts2; + private final Either ts3; + private final Either ts4; + + private For4Either(Either ts1, Either ts2, Either ts3, Either ts4) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + } + + /** + * Yields a result for elements of the cross-product of the underlying Eithers. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Either} elements + * @return an {@code Either} of mapped results + */ + public Either yield(Function4 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.flatMap(t3 -> + ts4.map(t4 -> f.apply(t1, t2, t3, t4))))); + } + + } + + /** + * For-comprehension with 5 Eithers. + */ + public static class For5Either { + + private final Either ts1; + private final Either ts2; + private final Either ts3; + private final Either ts4; + private final Either ts5; + + private For5Either(Either ts1, Either ts2, Either ts3, Either ts4, Either ts5) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + } + + /** + * Yields a result for elements of the cross-product of the underlying Eithers. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Either} elements + * @return an {@code Either} of mapped results + */ + public Either yield(Function5 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.flatMap(t3 -> + ts4.flatMap(t4 -> + ts5.map(t5 -> f.apply(t1, t2, t3, t4, t5)))))); + } + + } + + /** + * For-comprehension with 6 Eithers. + */ + public static class For6Either { + + private final Either ts1; + private final Either ts2; + private final Either ts3; + private final Either ts4; + private final Either ts5; + private final Either ts6; + + private For6Either(Either ts1, Either ts2, Either ts3, Either ts4, Either ts5, Either ts6) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + } + + /** + * Yields a result for elements of the cross-product of the underlying Eithers. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Either} elements + * @return an {@code Either} of mapped results + */ + public Either yield(Function6 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.flatMap(t3 -> + ts4.flatMap(t4 -> + ts5.flatMap(t5 -> + ts6.map(t6 -> f.apply(t1, t2, t3, t4, t5, t6))))))); + } + + } + + /** + * For-comprehension with 7 Eithers. + */ + public static class For7Either { + + private final Either ts1; + private final Either ts2; + private final Either ts3; + private final Either ts4; + private final Either ts5; + private final Either ts6; + private final Either ts7; + + private For7Either(Either ts1, Either ts2, Either ts3, Either ts4, Either ts5, Either ts6, Either ts7) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + this.ts7 = ts7; + } + + /** + * Yields a result for elements of the cross-product of the underlying Eithers. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Either} elements + * @return an {@code Either} of mapped results + */ + public Either yield(Function7 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.flatMap(t3 -> + ts4.flatMap(t4 -> + ts5.flatMap(t5 -> + ts6.flatMap(t6 -> + ts7.map(t7 -> f.apply(t1, t2, t3, t4, t5, t6, t7)))))))); + } + + } + + /** + * For-comprehension with 8 Eithers. + */ + public static class For8Either { + + private final Either ts1; + private final Either ts2; + private final Either ts3; + private final Either ts4; + private final Either ts5; + private final Either ts6; + private final Either ts7; + private final Either ts8; + + private For8Either(Either ts1, Either ts2, Either ts3, Either ts4, Either ts5, Either ts6, Either ts7, Either ts8) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + this.ts7 = ts7; + this.ts8 = ts8; + } + + /** + * Yields a result for elements of the cross-product of the underlying Eithers. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Either} elements + * @return an {@code Either} of mapped results + */ + public Either yield(Function8 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.flatMap(t3 -> + ts4.flatMap(t4 -> + ts5.flatMap(t5 -> + ts6.flatMap(t6 -> + ts7.flatMap(t7 -> + ts8.map(t8 -> f.apply(t1, t2, t3, t4, t5, t6, t7, t8))))))))); + } + + } + + /** + * For-comprehension with one Validation. + */ + public static class For1Validation { + + private final Validation ts1; + + private For1Validation(Validation ts1) { + this.ts1 = ts1; + } + + /** + * Yields a result for elements of the cross-product of the underlying Validation. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Validation} elements + * @return an {@code Validation} of mapped results + */ + public Validation yield(Function f) { + Objects.requireNonNull(f, "f is null"); + return ts1.map(f); + } + + /** + * A shortcut for {@code yield(Function.identity())}. + * + * @return an {@code Iterator} of mapped results + */ + public Validation yield() { + return this.yield(Function.identity()); + } + } + + /** + * For-comprehension with two Validations. + */ + public static class For2Validation { + + private final Validation ts1; + private final Validation ts2; + + private For2Validation(Validation ts1, Validation ts2) { + this.ts1 = ts1; + this.ts2 = ts2; + } + + /** + * Yields a result for elements of the cross-product of the underlying Validations. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Validation} elements + * @return an {@code Validation} of mapped results + */ + public Validation yield(BiFunction f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.map(t2 -> f.apply(t1, t2))); + } + + } + + /** + * For-comprehension with three Validations. + */ + public static class For3Validation { + + private final Validation ts1; + private final Validation ts2; + private final Validation ts3; + + private For3Validation(Validation ts1, Validation ts2, Validation ts3) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + } + + /** + * Yields a result for elements of the cross-product of the underlying Validations. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Validation} elements + * @return an {@code Validation} of mapped results + */ + public Validation yield(Function3 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.map(t3 -> f.apply(t1, t2, t3)))); + } + + } + + /** + * For-comprehension with 4 Validations. + */ + public static class For4Validation { + + private final Validation ts1; + private final Validation ts2; + private final Validation ts3; + private final Validation ts4; + + private For4Validation(Validation ts1, Validation ts2, Validation ts3, Validation ts4) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + } + + /** + * Yields a result for elements of the cross-product of the underlying Validations. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Validation} elements + * @return an {@code Validation} of mapped results + */ + public Validation yield(Function4 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.flatMap(t3 -> + ts4.map(t4 -> f.apply(t1, t2, t3, t4))))); + } + + } + + /** + * For-comprehension with 5 Validations. + */ + public static class For5Validation { + + private final Validation ts1; + private final Validation ts2; + private final Validation ts3; + private final Validation ts4; + private final Validation ts5; + + private For5Validation(Validation ts1, Validation ts2, Validation ts3, Validation ts4, Validation ts5) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + } + + /** + * Yields a result for elements of the cross-product of the underlying Validations. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Validation} elements + * @return an {@code Validation} of mapped results + */ + public Validation yield(Function5 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.flatMap(t3 -> + ts4.flatMap(t4 -> + ts5.map(t5 -> f.apply(t1, t2, t3, t4, t5)))))); + } + + } + + /** + * For-comprehension with 6 Validations. + */ + public static class For6Validation { + + private final Validation ts1; + private final Validation ts2; + private final Validation ts3; + private final Validation ts4; + private final Validation ts5; + private final Validation ts6; + + private For6Validation(Validation ts1, Validation ts2, Validation ts3, Validation ts4, Validation ts5, Validation ts6) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + } + + /** + * Yields a result for elements of the cross-product of the underlying Validations. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Validation} elements + * @return an {@code Validation} of mapped results + */ + public Validation yield(Function6 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.flatMap(t3 -> + ts4.flatMap(t4 -> + ts5.flatMap(t5 -> + ts6.map(t6 -> f.apply(t1, t2, t3, t4, t5, t6))))))); + } + + } + + /** + * For-comprehension with 7 Validations. + */ + public static class For7Validation { + + private final Validation ts1; + private final Validation ts2; + private final Validation ts3; + private final Validation ts4; + private final Validation ts5; + private final Validation ts6; + private final Validation ts7; + + private For7Validation(Validation ts1, Validation ts2, Validation ts3, Validation ts4, Validation ts5, Validation ts6, Validation ts7) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + this.ts7 = ts7; + } + + /** + * Yields a result for elements of the cross-product of the underlying Validations. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Validation} elements + * @return an {@code Validation} of mapped results + */ + public Validation yield(Function7 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.flatMap(t3 -> + ts4.flatMap(t4 -> + ts5.flatMap(t5 -> + ts6.flatMap(t6 -> + ts7.map(t7 -> f.apply(t1, t2, t3, t4, t5, t6, t7)))))))); + } + + } + + /** + * For-comprehension with 8 Validations. + */ + public static class For8Validation { + + private final Validation ts1; + private final Validation ts2; + private final Validation ts3; + private final Validation ts4; + private final Validation ts5; + private final Validation ts6; + private final Validation ts7; + private final Validation ts8; + + private For8Validation(Validation ts1, Validation ts2, Validation ts3, Validation ts4, Validation ts5, Validation ts6, Validation ts7, Validation ts8) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + this.ts7 = ts7; + this.ts8 = ts8; + } + + /** + * Yields a result for elements of the cross-product of the underlying Validations. + * + * @param f a function that maps an element of the cross-product to a result + * @param type of the resulting {@code Validation} elements + * @return an {@code Validation} of mapped results + */ + public Validation yield(Function8 f) { + Objects.requireNonNull(f, "f is null"); + return + ts1.flatMap(t1 -> + ts2.flatMap(t2 -> + ts3.flatMap(t3 -> + ts4.flatMap(t4 -> + ts5.flatMap(t5 -> + ts6.flatMap(t6 -> + ts7.flatMap(t7 -> + ts8.map(t8 -> f.apply(t1, t2, t3, t4, t5, t6, t7, t8))))))))); + } + + } + // // Structural Pattern Matching // diff --git a/vavr/src-gen/test/java/io/vavr/APITest.java b/vavr/src-gen/test/java/io/vavr/APITest.java index fa2ffc472..f9e8e13d9 100644 --- a/vavr/src-gen/test/java/io/vavr/APITest.java +++ b/vavr/src-gen/test/java/io/vavr/APITest.java @@ -33,8 +33,10 @@ import io.vavr.collection.Seq; import io.vavr.collection.Stream; import io.vavr.concurrent.Future; +import io.vavr.control.Either; import io.vavr.control.Option; import io.vavr.control.Try; +import io.vavr.control.Validation; import java.util.Arrays; import java.util.Comparator; import java.util.concurrent.Executors; @@ -1177,6 +1179,190 @@ public void shouldIterateForOption8() { assertThat(result.get()).isEqualTo(36); } + @Test + public void shouldIterateForEither1() { + final Either result = For( + Either.right(1) + ).yield(i1 -> i1); + assertThat(result.get()).isEqualTo(1); + } + + @Test + public void shouldIterateForEither2() { + final Either result = For( + Either.right(1), + Either.right(2) + ).yield((i1, i2) -> i1 + i2); + assertThat(result.get()).isEqualTo(3); + } + + @Test + public void shouldIterateForEither3() { + final Either result = For( + Either.right(1), + Either.right(2), + Either.right(3) + ).yield((i1, i2, i3) -> i1 + i2 + i3); + assertThat(result.get()).isEqualTo(6); + } + + @Test + public void shouldIterateForEither4() { + final Either result = For( + Either.right(1), + Either.right(2), + Either.right(3), + Either.right(4) + ).yield((i1, i2, i3, i4) -> i1 + i2 + i3 + i4); + assertThat(result.get()).isEqualTo(10); + } + + @Test + public void shouldIterateForEither5() { + final Either result = For( + Either.right(1), + Either.right(2), + Either.right(3), + Either.right(4), + Either.right(5) + ).yield((i1, i2, i3, i4, i5) -> i1 + i2 + i3 + i4 + i5); + assertThat(result.get()).isEqualTo(15); + } + + @Test + public void shouldIterateForEither6() { + final Either result = For( + Either.right(1), + Either.right(2), + Either.right(3), + Either.right(4), + Either.right(5), + Either.right(6) + ).yield((i1, i2, i3, i4, i5, i6) -> i1 + i2 + i3 + i4 + i5 + i6); + assertThat(result.get()).isEqualTo(21); + } + + @Test + public void shouldIterateForEither7() { + final Either result = For( + Either.right(1), + Either.right(2), + Either.right(3), + Either.right(4), + Either.right(5), + Either.right(6), + Either.right(7) + ).yield((i1, i2, i3, i4, i5, i6, i7) -> i1 + i2 + i3 + i4 + i5 + i6 + i7); + assertThat(result.get()).isEqualTo(28); + } + + @Test + public void shouldIterateForEither8() { + final Either result = For( + Either.right(1), + Either.right(2), + Either.right(3), + Either.right(4), + Either.right(5), + Either.right(6), + Either.right(7), + Either.right(8) + ).yield((i1, i2, i3, i4, i5, i6, i7, i8) -> i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8); + assertThat(result.get()).isEqualTo(36); + } + + @Test + public void shouldIterateForValidation1() { + final Validation result = For( + Validation.valid(1) + ).yield(i1 -> i1); + assertThat(result.get()).isEqualTo(1); + } + + @Test + public void shouldIterateForValidation2() { + final Validation result = For( + Validation.valid(1), + Validation.valid(2) + ).yield((i1, i2) -> i1 + i2); + assertThat(result.get()).isEqualTo(3); + } + + @Test + public void shouldIterateForValidation3() { + final Validation result = For( + Validation.valid(1), + Validation.valid(2), + Validation.valid(3) + ).yield((i1, i2, i3) -> i1 + i2 + i3); + assertThat(result.get()).isEqualTo(6); + } + + @Test + public void shouldIterateForValidation4() { + final Validation result = For( + Validation.valid(1), + Validation.valid(2), + Validation.valid(3), + Validation.valid(4) + ).yield((i1, i2, i3, i4) -> i1 + i2 + i3 + i4); + assertThat(result.get()).isEqualTo(10); + } + + @Test + public void shouldIterateForValidation5() { + final Validation result = For( + Validation.valid(1), + Validation.valid(2), + Validation.valid(3), + Validation.valid(4), + Validation.valid(5) + ).yield((i1, i2, i3, i4, i5) -> i1 + i2 + i3 + i4 + i5); + assertThat(result.get()).isEqualTo(15); + } + + @Test + public void shouldIterateForValidation6() { + final Validation result = For( + Validation.valid(1), + Validation.valid(2), + Validation.valid(3), + Validation.valid(4), + Validation.valid(5), + Validation.valid(6) + ).yield((i1, i2, i3, i4, i5, i6) -> i1 + i2 + i3 + i4 + i5 + i6); + assertThat(result.get()).isEqualTo(21); + } + + @Test + public void shouldIterateForValidation7() { + final Validation result = For( + Validation.valid(1), + Validation.valid(2), + Validation.valid(3), + Validation.valid(4), + Validation.valid(5), + Validation.valid(6), + Validation.valid(7) + ).yield((i1, i2, i3, i4, i5, i6, i7) -> i1 + i2 + i3 + i4 + i5 + i6 + i7); + assertThat(result.get()).isEqualTo(28); + } + + @Test + public void shouldIterateForValidation8() { + final Validation result = For( + Validation.valid(1), + Validation.valid(2), + Validation.valid(3), + Validation.valid(4), + Validation.valid(5), + Validation.valid(6), + Validation.valid(7), + Validation.valid(8) + ).yield((i1, i2, i3, i4, i5, i6, i7, i8) -> i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8); + assertThat(result.get()).isEqualTo(36); + } + @Test public void shouldIterateForFuture1() { final Future result = For(