diff --git a/vavr/generator/Generator.scala b/vavr/generator/Generator.scala index 7bf4464945..2060fdce54 100644 --- a/vavr/generator/Generator.scala +++ b/vavr/generator/Generator.scala @@ -743,6 +743,151 @@ def generateMainClasses(): Unit = { """ } + def genLazyFor(im: ImportManager, packageName: String, className: String): String = { + xs""" + ${ + monadicTypesFor + .filterNot(_ == "Iterable") + .gen(mtype => (2 to N).gen(i => { + val forClassName = s"ForLazy$i$mtype" + 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 => + if (j == 1) + s"$mtype<${parameterInset}T1> ts1" + else { + val inputTypes = (1 until j).gen(k => s"? super T$k")(", ") + s"Function${j - 1}<$inputTypes, $mtype<${parameterInset}T$j>> ts$j" + } + }(", ") + + val ctorArgs = (1 to i).gen(j => s"ts$j")(", ") + + xs""" + /$javadoc + * Creates a lazy {@code For}-comprehension over ${i.numerus(mtype)}. + * + *

The first argument ({@code ts1}) is the initial ${mtype}. Each subsequent + * argument ({@code ts2} .. {@code ts$i}) is a function that receives all values + * bound so far and returns the next ${mtype}. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + ${(0 to i).gen(j => if (j == 0) "*" else s"* @param ts$j the ${j.ordinal} ${mtype}")("\n")} + ${if (isComplex) s"* @param the common left-hand type of all ${mtype}s\n" else ""} + ${(1 to i).gen(j => s"* @param the component type of the ${j.ordinal} ${mtype}")("\n")} + * @return a new {@code $forClassName} builder of arity $i + * @throws NullPointerException if any argument is {@code null} + */ + public static <$generics> $forClassName<$generics> For($params) { + ${(1 to i).gen(j => xs"""$Objects.requireNonNull(ts$j, "ts$j is null");""")("\n")} + return new $forClassName<>($ctorArgs); + } + """ + })("\n\n"))("\n\n") + } + + ${ + monadicTypesFor + .filterNot(_ == "Iterable") + .gen(mtype => (2 to N).gen(i => { + val rtype = mtype + val forClassName = s"ForLazy$i$mtype" + val parameterInset = if (monadicTypesThatNeedParameter.contains(mtype)) "L, " else "" + val generics = parameterInset + (1 to i).gen(j => s"T$j")(", ") + + val fields = (1 to i).gen { j => + if (j == 1) + s"private final $mtype<${parameterInset}T1> ts1;" + else { + val inputTypes = (1 until j).gen(k => s"? super T$k")(", ") + s"private final Function${j - 1}<$inputTypes, $mtype<${parameterInset}T$j>> ts$j;" + } + }("\n") + + val ctorParams = (1 to i).gen { j => + if (j == 1) + s"$mtype<${parameterInset}T1> ts1" + else { + val inputTypes = (1 until j).gen(k => s"? super T$k")(", ") + s"Function${j - 1}<$inputTypes, $mtype<${parameterInset}T$j>> ts$j" + } + }(", ") + + val assignments = (1 to i).gen(j => s"this.ts$j = ts$j;")("\n") + + val yieldBody = { + def nestedLambda(j: Int): String = { + val base = " " * 23 + val indent = " " * (j + 1) + if (j == i) { + val argsList = (1 to i).map(k => s"t$k").mkString(", ") + val inputArgs = (1 until i).map(k => s"t$k").mkString(", ") + s"ts$i.apply($inputArgs).map(t$i -> f.apply($argsList))" + } else if (j == 1) { + s"ts1.flatMap(t1 -> {\n" + + s"${base}${indent} return ${nestedLambda(j + 1)};\n" + + s"${base}${indent}})" + } else { + val inputArgs = (1 until j).map(k => s"t$k").mkString(", ") + s"ts$j.apply($inputArgs).flatMap(t$j -> {\n" + + s"${base}${indent} return ${nestedLambda(j + 1)};\n" + + s"${base}${indent}})" + } + } + + nestedLambda(1) + } + + xs""" + /$javadoc + * A lazily evaluated {@code For}-comprehension with ${i.numerus(mtype)}. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying ${i.plural(mtype)} are traversed + * only when {@code yield(...)} is invoked.

+ * + ${if (monadicTypesThatNeedParameter.contains(mtype)) s"* @param the common left-hand type of all ${mtype}s\n" else ""} + ${(1 to i).gen(j => s"* @param the component type of the ${j.ordinal} ${mtype}")("\n")} + */ + public static class $forClassName<$generics> { + + $fields + + private $forClassName($ctorParams) { + $assignments + } + + /$javadoc + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying ${i.plural(mtype)} by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code $rtype} + * @return an {@code $rtype} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public $rtype<${parameterInset}R> yield(${ + if (i == 2) + s"BiFunction" + else + s"Function$i<${(1 to i).map(j => s"? super T$j").mkString(", ")}, ? extends R>" + } f) { + $Objects.requireNonNull(f, "f is null"); + return $yieldBody; + } + } + """ + })("\n\n"))("\n\n") + } + """ + } + + def genFor(im: ImportManager, packageName: String, className: String): String = { xs""" // @@ -1440,6 +1585,8 @@ def generateMainClasses(): Unit = { ${genFor(im, packageName, className)} + ${genLazyFor(im, packageName, className)} + ${genMatch(im, packageName, className)} } """ @@ -2975,8 +3122,27 @@ def generateTestClasses(): Unit = { ).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}); } + + @$test + public void shouldIterateLazyFor$mtype$i() { + final $mtype<${parameterInset}Integer> result = For( + ${(1 to i).gen(j => if (j == 1) { + s"$mtype.${builderName}($j)" + } else { + val args = (1 until j).map(k => s"r$k").mkString(", ") + val argsUsed = (1 until j).map(k => s"r$k").mkString(" + ") + s"($args) -> $mtype.${builderName}(${argsUsed} + $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")(" + ")}); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << ($i + 1)) - 2 - $i); + } """})("\n\n"))("\n\n")} + ${monadicFunctionTypesFor.gen(mtype => (1 to N).gen(i => { xs""" @$test public void shouldIterateFor$mtype$i() { diff --git a/vavr/src-gen/main/java/io/vavr/API.java b/vavr/src-gen/main/java/io/vavr/API.java index 99c8a182b1..f1653a5afa 100644 --- a/vavr/src-gen/main/java/io/vavr/API.java +++ b/vavr/src-gen/main/java/io/vavr/API.java @@ -5740,6 +5740,3702 @@ public Validation yield(Function8The first argument ({@code ts1}) is the initial Option. Each subsequent + * argument ({@code ts2} .. {@code ts2}) is a function that receives all values + * bound so far and returns the next Option. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Option + * @param ts2 the 2nd Option + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @return a new {@code ForLazy2Option} builder of arity 2 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy2Option For(Option ts1, Function1> ts2) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + return new ForLazy2Option<>(ts1, ts2); + } + + /** + * Creates a lazy {@code For}-comprehension over three Options. + * + *

The first argument ({@code ts1}) is the initial Option. Each subsequent + * argument ({@code ts2} .. {@code ts3}) is a function that receives all values + * bound so far and returns the next Option. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Option + * @param ts2 the 2nd Option + * @param ts3 the 3rd Option + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + * @return a new {@code ForLazy3Option} builder of arity 3 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy3Option For(Option ts1, Function1> ts2, Function2> ts3) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + return new ForLazy3Option<>(ts1, ts2, ts3); + } + + /** + * Creates a lazy {@code For}-comprehension over 4 Options. + * + *

The first argument ({@code ts1}) is the initial Option. Each subsequent + * argument ({@code ts2} .. {@code ts4}) is a function that receives all values + * bound so far and returns the next Option. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Option + * @param ts2 the 2nd Option + * @param ts3 the 3rd Option + * @param ts4 the 4th Option + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + * @param the component type of the 4th Option + * @return a new {@code ForLazy4Option} builder of arity 4 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy4Option For(Option ts1, Function1> ts2, Function2> ts3, Function3> 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 ForLazy4Option<>(ts1, ts2, ts3, ts4); + } + + /** + * Creates a lazy {@code For}-comprehension over 5 Options. + * + *

The first argument ({@code ts1}) is the initial Option. Each subsequent + * argument ({@code ts2} .. {@code ts5}) is a function that receives all values + * bound so far and returns the next Option. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Option + * @param ts2 the 2nd Option + * @param ts3 the 3rd Option + * @param ts4 the 4th Option + * @param ts5 the 5th Option + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + * @param the component type of the 4th Option + * @param the component type of the 5th Option + * @return a new {@code ForLazy5Option} builder of arity 5 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy5Option For(Option ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> 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 ForLazy5Option<>(ts1, ts2, ts3, ts4, ts5); + } + + /** + * Creates a lazy {@code For}-comprehension over 6 Options. + * + *

The first argument ({@code ts1}) is the initial Option. Each subsequent + * argument ({@code ts2} .. {@code ts6}) is a function that receives all values + * bound so far and returns the next Option. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Option + * @param ts2 the 2nd Option + * @param ts3 the 3rd Option + * @param ts4 the 4th Option + * @param ts5 the 5th Option + * @param ts6 the 6th Option + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + * @param the component type of the 4th Option + * @param the component type of the 5th Option + * @param the component type of the 6th Option + * @return a new {@code ForLazy6Option} builder of arity 6 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy6Option For(Option ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> 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 ForLazy6Option<>(ts1, ts2, ts3, ts4, ts5, ts6); + } + + /** + * Creates a lazy {@code For}-comprehension over 7 Options. + * + *

The first argument ({@code ts1}) is the initial Option. Each subsequent + * argument ({@code ts2} .. {@code ts7}) is a function that receives all values + * bound so far and returns the next Option. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Option + * @param ts2 the 2nd Option + * @param ts3 the 3rd Option + * @param ts4 the 4th Option + * @param ts5 the 5th Option + * @param ts6 the 6th Option + * @param ts7 the 7th Option + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + * @param the component type of the 4th Option + * @param the component type of the 5th Option + * @param the component type of the 6th Option + * @param the component type of the 7th Option + * @return a new {@code ForLazy7Option} builder of arity 7 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy7Option For(Option ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> 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 ForLazy7Option<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7); + } + + /** + * Creates a lazy {@code For}-comprehension over 8 Options. + * + *

The first argument ({@code ts1}) is the initial Option. Each subsequent + * argument ({@code ts2} .. {@code ts8}) is a function that receives all values + * bound so far and returns the next Option. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Option + * @param ts2 the 2nd Option + * @param ts3 the 3rd Option + * @param ts4 the 4th Option + * @param ts5 the 5th Option + * @param ts6 the 6th Option + * @param ts7 the 7th Option + * @param ts8 the 8th Option + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + * @param the component type of the 4th Option + * @param the component type of the 5th Option + * @param the component type of the 6th Option + * @param the component type of the 7th Option + * @param the component type of the 8th Option + * @return a new {@code ForLazy8Option} builder of arity 8 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy8Option For(Option ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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 ForLazy8Option<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7, ts8); + } + + /** + * Creates a lazy {@code For}-comprehension over two Futures. + * + *

The first argument ({@code ts1}) is the initial Future. Each subsequent + * argument ({@code ts2} .. {@code ts2}) is a function that receives all values + * bound so far and returns the next Future. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Future + * @param ts2 the 2nd Future + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @return a new {@code ForLazy2Future} builder of arity 2 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy2Future For(Future ts1, Function1> ts2) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + return new ForLazy2Future<>(ts1, ts2); + } + + /** + * Creates a lazy {@code For}-comprehension over three Futures. + * + *

The first argument ({@code ts1}) is the initial Future. Each subsequent + * argument ({@code ts2} .. {@code ts3}) is a function that receives all values + * bound so far and returns the next Future. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Future + * @param ts2 the 2nd Future + * @param ts3 the 3rd Future + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + * @return a new {@code ForLazy3Future} builder of arity 3 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy3Future For(Future ts1, Function1> ts2, Function2> ts3) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + return new ForLazy3Future<>(ts1, ts2, ts3); + } + + /** + * Creates a lazy {@code For}-comprehension over 4 Futures. + * + *

The first argument ({@code ts1}) is the initial Future. Each subsequent + * argument ({@code ts2} .. {@code ts4}) is a function that receives all values + * bound so far and returns the next Future. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Future + * @param ts2 the 2nd Future + * @param ts3 the 3rd Future + * @param ts4 the 4th Future + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + * @param the component type of the 4th Future + * @return a new {@code ForLazy4Future} builder of arity 4 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy4Future For(Future ts1, Function1> ts2, Function2> ts3, Function3> 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 ForLazy4Future<>(ts1, ts2, ts3, ts4); + } + + /** + * Creates a lazy {@code For}-comprehension over 5 Futures. + * + *

The first argument ({@code ts1}) is the initial Future. Each subsequent + * argument ({@code ts2} .. {@code ts5}) is a function that receives all values + * bound so far and returns the next Future. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Future + * @param ts2 the 2nd Future + * @param ts3 the 3rd Future + * @param ts4 the 4th Future + * @param ts5 the 5th Future + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + * @param the component type of the 4th Future + * @param the component type of the 5th Future + * @return a new {@code ForLazy5Future} builder of arity 5 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy5Future For(Future ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> 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 ForLazy5Future<>(ts1, ts2, ts3, ts4, ts5); + } + + /** + * Creates a lazy {@code For}-comprehension over 6 Futures. + * + *

The first argument ({@code ts1}) is the initial Future. Each subsequent + * argument ({@code ts2} .. {@code ts6}) is a function that receives all values + * bound so far and returns the next Future. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Future + * @param ts2 the 2nd Future + * @param ts3 the 3rd Future + * @param ts4 the 4th Future + * @param ts5 the 5th Future + * @param ts6 the 6th Future + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + * @param the component type of the 4th Future + * @param the component type of the 5th Future + * @param the component type of the 6th Future + * @return a new {@code ForLazy6Future} builder of arity 6 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy6Future For(Future ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> 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 ForLazy6Future<>(ts1, ts2, ts3, ts4, ts5, ts6); + } + + /** + * Creates a lazy {@code For}-comprehension over 7 Futures. + * + *

The first argument ({@code ts1}) is the initial Future. Each subsequent + * argument ({@code ts2} .. {@code ts7}) is a function that receives all values + * bound so far and returns the next Future. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Future + * @param ts2 the 2nd Future + * @param ts3 the 3rd Future + * @param ts4 the 4th Future + * @param ts5 the 5th Future + * @param ts6 the 6th Future + * @param ts7 the 7th Future + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + * @param the component type of the 4th Future + * @param the component type of the 5th Future + * @param the component type of the 6th Future + * @param the component type of the 7th Future + * @return a new {@code ForLazy7Future} builder of arity 7 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy7Future For(Future ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> 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 ForLazy7Future<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7); + } + + /** + * Creates a lazy {@code For}-comprehension over 8 Futures. + * + *

The first argument ({@code ts1}) is the initial Future. Each subsequent + * argument ({@code ts2} .. {@code ts8}) is a function that receives all values + * bound so far and returns the next Future. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Future + * @param ts2 the 2nd Future + * @param ts3 the 3rd Future + * @param ts4 the 4th Future + * @param ts5 the 5th Future + * @param ts6 the 6th Future + * @param ts7 the 7th Future + * @param ts8 the 8th Future + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + * @param the component type of the 4th Future + * @param the component type of the 5th Future + * @param the component type of the 6th Future + * @param the component type of the 7th Future + * @param the component type of the 8th Future + * @return a new {@code ForLazy8Future} builder of arity 8 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy8Future For(Future ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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 ForLazy8Future<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7, ts8); + } + + /** + * Creates a lazy {@code For}-comprehension over two Trys. + * + *

The first argument ({@code ts1}) is the initial Try. Each subsequent + * argument ({@code ts2} .. {@code ts2}) is a function that receives all values + * bound so far and returns the next Try. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Try + * @param ts2 the 2nd Try + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @return a new {@code ForLazy2Try} builder of arity 2 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy2Try For(Try ts1, Function1> ts2) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + return new ForLazy2Try<>(ts1, ts2); + } + + /** + * Creates a lazy {@code For}-comprehension over three Trys. + * + *

The first argument ({@code ts1}) is the initial Try. Each subsequent + * argument ({@code ts2} .. {@code ts3}) is a function that receives all values + * bound so far and returns the next Try. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Try + * @param ts2 the 2nd Try + * @param ts3 the 3rd Try + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + * @return a new {@code ForLazy3Try} builder of arity 3 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy3Try For(Try ts1, Function1> ts2, Function2> ts3) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + return new ForLazy3Try<>(ts1, ts2, ts3); + } + + /** + * Creates a lazy {@code For}-comprehension over 4 Trys. + * + *

The first argument ({@code ts1}) is the initial Try. Each subsequent + * argument ({@code ts2} .. {@code ts4}) is a function that receives all values + * bound so far and returns the next Try. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Try + * @param ts2 the 2nd Try + * @param ts3 the 3rd Try + * @param ts4 the 4th Try + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + * @param the component type of the 4th Try + * @return a new {@code ForLazy4Try} builder of arity 4 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy4Try For(Try ts1, Function1> ts2, Function2> ts3, Function3> 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 ForLazy4Try<>(ts1, ts2, ts3, ts4); + } + + /** + * Creates a lazy {@code For}-comprehension over 5 Trys. + * + *

The first argument ({@code ts1}) is the initial Try. Each subsequent + * argument ({@code ts2} .. {@code ts5}) is a function that receives all values + * bound so far and returns the next Try. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Try + * @param ts2 the 2nd Try + * @param ts3 the 3rd Try + * @param ts4 the 4th Try + * @param ts5 the 5th Try + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + * @param the component type of the 4th Try + * @param the component type of the 5th Try + * @return a new {@code ForLazy5Try} builder of arity 5 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy5Try For(Try ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> 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 ForLazy5Try<>(ts1, ts2, ts3, ts4, ts5); + } + + /** + * Creates a lazy {@code For}-comprehension over 6 Trys. + * + *

The first argument ({@code ts1}) is the initial Try. Each subsequent + * argument ({@code ts2} .. {@code ts6}) is a function that receives all values + * bound so far and returns the next Try. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Try + * @param ts2 the 2nd Try + * @param ts3 the 3rd Try + * @param ts4 the 4th Try + * @param ts5 the 5th Try + * @param ts6 the 6th Try + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + * @param the component type of the 4th Try + * @param the component type of the 5th Try + * @param the component type of the 6th Try + * @return a new {@code ForLazy6Try} builder of arity 6 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy6Try For(Try ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> 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 ForLazy6Try<>(ts1, ts2, ts3, ts4, ts5, ts6); + } + + /** + * Creates a lazy {@code For}-comprehension over 7 Trys. + * + *

The first argument ({@code ts1}) is the initial Try. Each subsequent + * argument ({@code ts2} .. {@code ts7}) is a function that receives all values + * bound so far and returns the next Try. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Try + * @param ts2 the 2nd Try + * @param ts3 the 3rd Try + * @param ts4 the 4th Try + * @param ts5 the 5th Try + * @param ts6 the 6th Try + * @param ts7 the 7th Try + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + * @param the component type of the 4th Try + * @param the component type of the 5th Try + * @param the component type of the 6th Try + * @param the component type of the 7th Try + * @return a new {@code ForLazy7Try} builder of arity 7 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy7Try For(Try ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> 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 ForLazy7Try<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7); + } + + /** + * Creates a lazy {@code For}-comprehension over 8 Trys. + * + *

The first argument ({@code ts1}) is the initial Try. Each subsequent + * argument ({@code ts2} .. {@code ts8}) is a function that receives all values + * bound so far and returns the next Try. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Try + * @param ts2 the 2nd Try + * @param ts3 the 3rd Try + * @param ts4 the 4th Try + * @param ts5 the 5th Try + * @param ts6 the 6th Try + * @param ts7 the 7th Try + * @param ts8 the 8th Try + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + * @param the component type of the 4th Try + * @param the component type of the 5th Try + * @param the component type of the 6th Try + * @param the component type of the 7th Try + * @param the component type of the 8th Try + * @return a new {@code ForLazy8Try} builder of arity 8 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy8Try For(Try ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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 ForLazy8Try<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7, ts8); + } + + /** + * Creates a lazy {@code For}-comprehension over two Lists. + * + *

The first argument ({@code ts1}) is the initial List. Each subsequent + * argument ({@code ts2} .. {@code ts2}) is a function that receives all values + * bound so far and returns the next List. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st List + * @param ts2 the 2nd List + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @return a new {@code ForLazy2List} builder of arity 2 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy2List For(List ts1, Function1> ts2) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + return new ForLazy2List<>(ts1, ts2); + } + + /** + * Creates a lazy {@code For}-comprehension over three Lists. + * + *

The first argument ({@code ts1}) is the initial List. Each subsequent + * argument ({@code ts2} .. {@code ts3}) is a function that receives all values + * bound so far and returns the next List. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st List + * @param ts2 the 2nd List + * @param ts3 the 3rd List + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + * @return a new {@code ForLazy3List} builder of arity 3 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy3List For(List ts1, Function1> ts2, Function2> ts3) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + return new ForLazy3List<>(ts1, ts2, ts3); + } + + /** + * Creates a lazy {@code For}-comprehension over 4 Lists. + * + *

The first argument ({@code ts1}) is the initial List. Each subsequent + * argument ({@code ts2} .. {@code ts4}) is a function that receives all values + * bound so far and returns the next List. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st List + * @param ts2 the 2nd List + * @param ts3 the 3rd List + * @param ts4 the 4th List + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + * @param the component type of the 4th List + * @return a new {@code ForLazy4List} builder of arity 4 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy4List For(List ts1, Function1> ts2, Function2> ts3, Function3> 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 ForLazy4List<>(ts1, ts2, ts3, ts4); + } + + /** + * Creates a lazy {@code For}-comprehension over 5 Lists. + * + *

The first argument ({@code ts1}) is the initial List. Each subsequent + * argument ({@code ts2} .. {@code ts5}) is a function that receives all values + * bound so far and returns the next List. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st List + * @param ts2 the 2nd List + * @param ts3 the 3rd List + * @param ts4 the 4th List + * @param ts5 the 5th List + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + * @param the component type of the 4th List + * @param the component type of the 5th List + * @return a new {@code ForLazy5List} builder of arity 5 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy5List For(List ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> 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 ForLazy5List<>(ts1, ts2, ts3, ts4, ts5); + } + + /** + * Creates a lazy {@code For}-comprehension over 6 Lists. + * + *

The first argument ({@code ts1}) is the initial List. Each subsequent + * argument ({@code ts2} .. {@code ts6}) is a function that receives all values + * bound so far and returns the next List. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st List + * @param ts2 the 2nd List + * @param ts3 the 3rd List + * @param ts4 the 4th List + * @param ts5 the 5th List + * @param ts6 the 6th List + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + * @param the component type of the 4th List + * @param the component type of the 5th List + * @param the component type of the 6th List + * @return a new {@code ForLazy6List} builder of arity 6 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy6List For(List ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> 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 ForLazy6List<>(ts1, ts2, ts3, ts4, ts5, ts6); + } + + /** + * Creates a lazy {@code For}-comprehension over 7 Lists. + * + *

The first argument ({@code ts1}) is the initial List. Each subsequent + * argument ({@code ts2} .. {@code ts7}) is a function that receives all values + * bound so far and returns the next List. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st List + * @param ts2 the 2nd List + * @param ts3 the 3rd List + * @param ts4 the 4th List + * @param ts5 the 5th List + * @param ts6 the 6th List + * @param ts7 the 7th List + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + * @param the component type of the 4th List + * @param the component type of the 5th List + * @param the component type of the 6th List + * @param the component type of the 7th List + * @return a new {@code ForLazy7List} builder of arity 7 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy7List For(List ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> 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 ForLazy7List<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7); + } + + /** + * Creates a lazy {@code For}-comprehension over 8 Lists. + * + *

The first argument ({@code ts1}) is the initial List. Each subsequent + * argument ({@code ts2} .. {@code ts8}) is a function that receives all values + * bound so far and returns the next List. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st List + * @param ts2 the 2nd List + * @param ts3 the 3rd List + * @param ts4 the 4th List + * @param ts5 the 5th List + * @param ts6 the 6th List + * @param ts7 the 7th List + * @param ts8 the 8th List + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + * @param the component type of the 4th List + * @param the component type of the 5th List + * @param the component type of the 6th List + * @param the component type of the 7th List + * @param the component type of the 8th List + * @return a new {@code ForLazy8List} builder of arity 8 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy8List For(List ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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 ForLazy8List<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7, ts8); + } + + /** + * Creates a lazy {@code For}-comprehension over two Eithers. + * + *

The first argument ({@code ts1}) is the initial Either. Each subsequent + * argument ({@code ts2} .. {@code ts2}) is a function that receives all values + * bound so far and returns the next Either. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Either + * @param ts2 the 2nd Either + * @param the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @return a new {@code ForLazy2Either} builder of arity 2 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy2Either For(Either ts1, Function1> ts2) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + return new ForLazy2Either<>(ts1, ts2); + } + + /** + * Creates a lazy {@code For}-comprehension over three Eithers. + * + *

The first argument ({@code ts1}) is the initial Either. Each subsequent + * argument ({@code ts2} .. {@code ts3}) is a function that receives all values + * bound so far and returns the next Either. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Either + * @param ts2 the 2nd Either + * @param ts3 the 3rd Either + * @param the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + * @return a new {@code ForLazy3Either} builder of arity 3 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy3Either For(Either ts1, Function1> ts2, Function2> ts3) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + return new ForLazy3Either<>(ts1, ts2, ts3); + } + + /** + * Creates a lazy {@code For}-comprehension over 4 Eithers. + * + *

The first argument ({@code ts1}) is the initial Either. Each subsequent + * argument ({@code ts2} .. {@code ts4}) is a function that receives all values + * bound so far and returns the next Either. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Either + * @param ts2 the 2nd Either + * @param ts3 the 3rd Either + * @param ts4 the 4th Either + * @param the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + * @param the component type of the 4th Either + * @return a new {@code ForLazy4Either} builder of arity 4 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy4Either For(Either ts1, Function1> ts2, Function2> ts3, Function3> 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 ForLazy4Either<>(ts1, ts2, ts3, ts4); + } + + /** + * Creates a lazy {@code For}-comprehension over 5 Eithers. + * + *

The first argument ({@code ts1}) is the initial Either. Each subsequent + * argument ({@code ts2} .. {@code ts5}) is a function that receives all values + * bound so far and returns the next Either. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @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 the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + * @param the component type of the 4th Either + * @param the component type of the 5th Either + * @return a new {@code ForLazy5Either} builder of arity 5 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy5Either For(Either ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> 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 ForLazy5Either<>(ts1, ts2, ts3, ts4, ts5); + } + + /** + * Creates a lazy {@code For}-comprehension over 6 Eithers. + * + *

The first argument ({@code ts1}) is the initial Either. Each subsequent + * argument ({@code ts2} .. {@code ts6}) is a function that receives all values + * bound so far and returns the next Either. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @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 the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + * @param the component type of the 4th Either + * @param the component type of the 5th Either + * @param the component type of the 6th Either + * @return a new {@code ForLazy6Either} builder of arity 6 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy6Either For(Either ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> 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 ForLazy6Either<>(ts1, ts2, ts3, ts4, ts5, ts6); + } + + /** + * Creates a lazy {@code For}-comprehension over 7 Eithers. + * + *

The first argument ({@code ts1}) is the initial Either. Each subsequent + * argument ({@code ts2} .. {@code ts7}) is a function that receives all values + * bound so far and returns the next Either. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @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 the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + * @param the component type of the 4th Either + * @param the component type of the 5th Either + * @param the component type of the 6th Either + * @param the component type of the 7th Either + * @return a new {@code ForLazy7Either} builder of arity 7 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy7Either For(Either ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> 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 ForLazy7Either<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7); + } + + /** + * Creates a lazy {@code For}-comprehension over 8 Eithers. + * + *

The first argument ({@code ts1}) is the initial Either. Each subsequent + * argument ({@code ts2} .. {@code ts8}) is a function that receives all values + * bound so far and returns the next Either. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @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 the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + * @param the component type of the 4th Either + * @param the component type of the 5th Either + * @param the component type of the 6th Either + * @param the component type of the 7th Either + * @param the component type of the 8th Either + * @return a new {@code ForLazy8Either} builder of arity 8 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy8Either For(Either ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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 ForLazy8Either<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7, ts8); + } + + /** + * Creates a lazy {@code For}-comprehension over two Validations. + * + *

The first argument ({@code ts1}) is the initial Validation. Each subsequent + * argument ({@code ts2} .. {@code ts2}) is a function that receives all values + * bound so far and returns the next Validation. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Validation + * @param ts2 the 2nd Validation + * @param the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @return a new {@code ForLazy2Validation} builder of arity 2 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy2Validation For(Validation ts1, Function1> ts2) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + return new ForLazy2Validation<>(ts1, ts2); + } + + /** + * Creates a lazy {@code For}-comprehension over three Validations. + * + *

The first argument ({@code ts1}) is the initial Validation. Each subsequent + * argument ({@code ts2} .. {@code ts3}) is a function that receives all values + * bound so far and returns the next Validation. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Validation + * @param ts2 the 2nd Validation + * @param ts3 the 3rd Validation + * @param the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + * @return a new {@code ForLazy3Validation} builder of arity 3 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy3Validation For(Validation ts1, Function1> ts2, Function2> ts3) { + Objects.requireNonNull(ts1, "ts1 is null"); + Objects.requireNonNull(ts2, "ts2 is null"); + Objects.requireNonNull(ts3, "ts3 is null"); + return new ForLazy3Validation<>(ts1, ts2, ts3); + } + + /** + * Creates a lazy {@code For}-comprehension over 4 Validations. + * + *

The first argument ({@code ts1}) is the initial Validation. Each subsequent + * argument ({@code ts2} .. {@code ts4}) is a function that receives all values + * bound so far and returns the next Validation. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @param ts1 the 1st Validation + * @param ts2 the 2nd Validation + * @param ts3 the 3rd Validation + * @param ts4 the 4th Validation + * @param the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + * @param the component type of the 4th Validation + * @return a new {@code ForLazy4Validation} builder of arity 4 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy4Validation For(Validation ts1, Function1> ts2, Function2> ts3, Function3> 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 ForLazy4Validation<>(ts1, ts2, ts3, ts4); + } + + /** + * Creates a lazy {@code For}-comprehension over 5 Validations. + * + *

The first argument ({@code ts1}) is the initial Validation. Each subsequent + * argument ({@code ts2} .. {@code ts5}) is a function that receives all values + * bound so far and returns the next Validation. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @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 the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + * @param the component type of the 4th Validation + * @param the component type of the 5th Validation + * @return a new {@code ForLazy5Validation} builder of arity 5 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy5Validation For(Validation ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> 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 ForLazy5Validation<>(ts1, ts2, ts3, ts4, ts5); + } + + /** + * Creates a lazy {@code For}-comprehension over 6 Validations. + * + *

The first argument ({@code ts1}) is the initial Validation. Each subsequent + * argument ({@code ts2} .. {@code ts6}) is a function that receives all values + * bound so far and returns the next Validation. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @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 the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + * @param the component type of the 4th Validation + * @param the component type of the 5th Validation + * @param the component type of the 6th Validation + * @return a new {@code ForLazy6Validation} builder of arity 6 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy6Validation For(Validation ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> 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 ForLazy6Validation<>(ts1, ts2, ts3, ts4, ts5, ts6); + } + + /** + * Creates a lazy {@code For}-comprehension over 7 Validations. + * + *

The first argument ({@code ts1}) is the initial Validation. Each subsequent + * argument ({@code ts2} .. {@code ts7}) is a function that receives all values + * bound so far and returns the next Validation. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @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 the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + * @param the component type of the 4th Validation + * @param the component type of the 5th Validation + * @param the component type of the 6th Validation + * @param the component type of the 7th Validation + * @return a new {@code ForLazy7Validation} builder of arity 7 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy7Validation For(Validation ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> 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 ForLazy7Validation<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7); + } + + /** + * Creates a lazy {@code For}-comprehension over 8 Validations. + * + *

The first argument ({@code ts1}) is the initial Validation. Each subsequent + * argument ({@code ts2} .. {@code ts8}) is a function that receives all values + * bound so far and returns the next Validation. This method only constructs the + * lazy comprehension; underlying effects are evaluated when {@code yield(...)} + * is invoked.

+ * + * + * @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 the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + * @param the component type of the 4th Validation + * @param the component type of the 5th Validation + * @param the component type of the 6th Validation + * @param the component type of the 7th Validation + * @param the component type of the 8th Validation + * @return a new {@code ForLazy8Validation} builder of arity 8 + * @throws NullPointerException if any argument is {@code null} + */ + public static ForLazy8Validation For(Validation ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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 ForLazy8Validation<>(ts1, ts2, ts3, ts4, ts5, ts6, ts7, ts8); + } + + /** + * A lazily evaluated {@code For}-comprehension with two Options. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Options are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + */ + public static class ForLazy2Option { + + private final Option ts1; + private final Function1> ts2; + + private ForLazy2Option(Option ts1, Function1> ts2) { + this.ts1 = ts1; + this.ts2 = ts2; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Options by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Option} + * @return an {@code Option} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Option yield(BiFunction f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).map(t2 -> f.apply(t1, t2)); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with three Options. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Options are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + */ + public static class ForLazy3Option { + + private final Option ts1; + private final Function1> ts2; + private final Function2> ts3; + + private ForLazy3Option(Option ts1, Function1> ts2, Function2> ts3) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Options by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Option} + * @return an {@code Option} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Option yield(Function3 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).map(t3 -> f.apply(t1, t2, t3)); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 4 Options. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Options are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + * @param the component type of the 4th Option + */ + public static class ForLazy4Option { + + private final Option ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + + private ForLazy4Option(Option ts1, Function1> ts2, Function2> ts3, Function3> ts4) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Options by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Option} + * @return an {@code Option} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Option yield(Function4 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).map(t4 -> f.apply(t1, t2, t3, t4)); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 5 Options. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Options are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + * @param the component type of the 4th Option + * @param the component type of the 5th Option + */ + public static class ForLazy5Option { + + private final Option ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + + private ForLazy5Option(Option ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Options by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Option} + * @return an {@code Option} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Option yield(Function5 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).map(t5 -> f.apply(t1, t2, t3, t4, t5)); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 6 Options. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Options are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + * @param the component type of the 4th Option + * @param the component type of the 5th Option + * @param the component type of the 6th Option + */ + public static class ForLazy6Option { + + private final Option ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + + private ForLazy6Option(Option ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Options by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Option} + * @return an {@code Option} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Option yield(Function6 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).map(t6 -> f.apply(t1, t2, t3, t4, t5, t6)); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 7 Options. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Options are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + * @param the component type of the 4th Option + * @param the component type of the 5th Option + * @param the component type of the 6th Option + * @param the component type of the 7th Option + */ + public static class ForLazy7Option { + + private final Option ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + + private ForLazy7Option(Option ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + this.ts7 = ts7; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Options by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Option} + * @return an {@code Option} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Option yield(Function7 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).map(t7 -> f.apply(t1, t2, t3, t4, t5, t6, t7)); + }); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 8 Options. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Options are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Option + * @param the component type of the 2nd Option + * @param the component type of the 3rd Option + * @param the component type of the 4th Option + * @param the component type of the 5th Option + * @param the component type of the 6th Option + * @param the component type of the 7th Option + * @param the component type of the 8th Option + */ + public static class ForLazy8Option { + + private final Option ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + private final Function7> ts8; + + private ForLazy8Option(Option ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Options by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Option} + * @return an {@code Option} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Option yield(Function8 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).flatMap(t7 -> { + return ts8.apply(t1, t2, t3, t4, t5, t6, t7).map(t8 -> f.apply(t1, t2, t3, t4, t5, t6, t7, t8)); + }); + }); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with two Futures. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Futures are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + */ + public static class ForLazy2Future { + + private final Future ts1; + private final Function1> ts2; + + private ForLazy2Future(Future ts1, Function1> ts2) { + this.ts1 = ts1; + this.ts2 = ts2; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Futures by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Future} + * @return an {@code Future} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Future yield(BiFunction f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).map(t2 -> f.apply(t1, t2)); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with three Futures. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Futures are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + */ + public static class ForLazy3Future { + + private final Future ts1; + private final Function1> ts2; + private final Function2> ts3; + + private ForLazy3Future(Future ts1, Function1> ts2, Function2> ts3) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Futures by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Future} + * @return an {@code Future} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Future yield(Function3 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).map(t3 -> f.apply(t1, t2, t3)); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 4 Futures. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Futures are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + * @param the component type of the 4th Future + */ + public static class ForLazy4Future { + + private final Future ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + + private ForLazy4Future(Future ts1, Function1> ts2, Function2> ts3, Function3> ts4) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Futures by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Future} + * @return an {@code Future} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Future yield(Function4 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).map(t4 -> f.apply(t1, t2, t3, t4)); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 5 Futures. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Futures are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + * @param the component type of the 4th Future + * @param the component type of the 5th Future + */ + public static class ForLazy5Future { + + private final Future ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + + private ForLazy5Future(Future ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Futures by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Future} + * @return an {@code Future} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Future yield(Function5 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).map(t5 -> f.apply(t1, t2, t3, t4, t5)); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 6 Futures. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Futures are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + * @param the component type of the 4th Future + * @param the component type of the 5th Future + * @param the component type of the 6th Future + */ + public static class ForLazy6Future { + + private final Future ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + + private ForLazy6Future(Future ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Futures by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Future} + * @return an {@code Future} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Future yield(Function6 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).map(t6 -> f.apply(t1, t2, t3, t4, t5, t6)); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 7 Futures. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Futures are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + * @param the component type of the 4th Future + * @param the component type of the 5th Future + * @param the component type of the 6th Future + * @param the component type of the 7th Future + */ + public static class ForLazy7Future { + + private final Future ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + + private ForLazy7Future(Future ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + this.ts7 = ts7; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Futures by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Future} + * @return an {@code Future} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Future yield(Function7 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).map(t7 -> f.apply(t1, t2, t3, t4, t5, t6, t7)); + }); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 8 Futures. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Futures are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Future + * @param the component type of the 2nd Future + * @param the component type of the 3rd Future + * @param the component type of the 4th Future + * @param the component type of the 5th Future + * @param the component type of the 6th Future + * @param the component type of the 7th Future + * @param the component type of the 8th Future + */ + public static class ForLazy8Future { + + private final Future ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + private final Function7> ts8; + + private ForLazy8Future(Future ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Futures by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Future} + * @return an {@code Future} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Future yield(Function8 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).flatMap(t7 -> { + return ts8.apply(t1, t2, t3, t4, t5, t6, t7).map(t8 -> f.apply(t1, t2, t3, t4, t5, t6, t7, t8)); + }); + }); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with two Trys. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Trys are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + */ + public static class ForLazy2Try { + + private final Try ts1; + private final Function1> ts2; + + private ForLazy2Try(Try ts1, Function1> ts2) { + this.ts1 = ts1; + this.ts2 = ts2; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Trys by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Try} + * @return an {@code Try} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Try yield(BiFunction f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).map(t2 -> f.apply(t1, t2)); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with three Trys. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Trys are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + */ + public static class ForLazy3Try { + + private final Try ts1; + private final Function1> ts2; + private final Function2> ts3; + + private ForLazy3Try(Try ts1, Function1> ts2, Function2> ts3) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Trys by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Try} + * @return an {@code Try} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Try yield(Function3 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).map(t3 -> f.apply(t1, t2, t3)); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 4 Trys. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Trys are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + * @param the component type of the 4th Try + */ + public static class ForLazy4Try { + + private final Try ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + + private ForLazy4Try(Try ts1, Function1> ts2, Function2> ts3, Function3> ts4) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Trys by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Try} + * @return an {@code Try} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Try yield(Function4 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).map(t4 -> f.apply(t1, t2, t3, t4)); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 5 Trys. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Trys are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + * @param the component type of the 4th Try + * @param the component type of the 5th Try + */ + public static class ForLazy5Try { + + private final Try ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + + private ForLazy5Try(Try ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Trys by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Try} + * @return an {@code Try} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Try yield(Function5 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).map(t5 -> f.apply(t1, t2, t3, t4, t5)); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 6 Trys. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Trys are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + * @param the component type of the 4th Try + * @param the component type of the 5th Try + * @param the component type of the 6th Try + */ + public static class ForLazy6Try { + + private final Try ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + + private ForLazy6Try(Try ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Trys by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Try} + * @return an {@code Try} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Try yield(Function6 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).map(t6 -> f.apply(t1, t2, t3, t4, t5, t6)); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 7 Trys. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Trys are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + * @param the component type of the 4th Try + * @param the component type of the 5th Try + * @param the component type of the 6th Try + * @param the component type of the 7th Try + */ + public static class ForLazy7Try { + + private final Try ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + + private ForLazy7Try(Try ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + this.ts7 = ts7; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Trys by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Try} + * @return an {@code Try} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Try yield(Function7 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).map(t7 -> f.apply(t1, t2, t3, t4, t5, t6, t7)); + }); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 8 Trys. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Trys are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st Try + * @param the component type of the 2nd Try + * @param the component type of the 3rd Try + * @param the component type of the 4th Try + * @param the component type of the 5th Try + * @param the component type of the 6th Try + * @param the component type of the 7th Try + * @param the component type of the 8th Try + */ + public static class ForLazy8Try { + + private final Try ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + private final Function7> ts8; + + private ForLazy8Try(Try ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Trys by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Try} + * @return an {@code Try} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Try yield(Function8 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).flatMap(t7 -> { + return ts8.apply(t1, t2, t3, t4, t5, t6, t7).map(t8 -> f.apply(t1, t2, t3, t4, t5, t6, t7, t8)); + }); + }); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with two Lists. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Lists are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st List + * @param the component type of the 2nd List + */ + public static class ForLazy2List { + + private final List ts1; + private final Function1> ts2; + + private ForLazy2List(List ts1, Function1> ts2) { + this.ts1 = ts1; + this.ts2 = ts2; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Lists by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code List} + * @return an {@code List} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public List yield(BiFunction f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).map(t2 -> f.apply(t1, t2)); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with three Lists. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Lists are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + */ + public static class ForLazy3List { + + private final List ts1; + private final Function1> ts2; + private final Function2> ts3; + + private ForLazy3List(List ts1, Function1> ts2, Function2> ts3) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Lists by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code List} + * @return an {@code List} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public List yield(Function3 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).map(t3 -> f.apply(t1, t2, t3)); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 4 Lists. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Lists are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + * @param the component type of the 4th List + */ + public static class ForLazy4List { + + private final List ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + + private ForLazy4List(List ts1, Function1> ts2, Function2> ts3, Function3> ts4) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Lists by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code List} + * @return an {@code List} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public List yield(Function4 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).map(t4 -> f.apply(t1, t2, t3, t4)); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 5 Lists. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Lists are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + * @param the component type of the 4th List + * @param the component type of the 5th List + */ + public static class ForLazy5List { + + private final List ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + + private ForLazy5List(List ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Lists by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code List} + * @return an {@code List} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public List yield(Function5 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).map(t5 -> f.apply(t1, t2, t3, t4, t5)); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 6 Lists. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Lists are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + * @param the component type of the 4th List + * @param the component type of the 5th List + * @param the component type of the 6th List + */ + public static class ForLazy6List { + + private final List ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + + private ForLazy6List(List ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Lists by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code List} + * @return an {@code List} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public List yield(Function6 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).map(t6 -> f.apply(t1, t2, t3, t4, t5, t6)); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 7 Lists. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Lists are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + * @param the component type of the 4th List + * @param the component type of the 5th List + * @param the component type of the 6th List + * @param the component type of the 7th List + */ + public static class ForLazy7List { + + private final List ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + + private ForLazy7List(List ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + this.ts7 = ts7; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Lists by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code List} + * @return an {@code List} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public List yield(Function7 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).map(t7 -> f.apply(t1, t2, t3, t4, t5, t6, t7)); + }); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 8 Lists. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Lists are traversed + * only when {@code yield(...)} is invoked.

+ * + + * @param the component type of the 1st List + * @param the component type of the 2nd List + * @param the component type of the 3rd List + * @param the component type of the 4th List + * @param the component type of the 5th List + * @param the component type of the 6th List + * @param the component type of the 7th List + * @param the component type of the 8th List + */ + public static class ForLazy8List { + + private final List ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + private final Function7> ts8; + + private ForLazy8List(List ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Lists by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code List} + * @return an {@code List} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public List yield(Function8 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).flatMap(t7 -> { + return ts8.apply(t1, t2, t3, t4, t5, t6, t7).map(t8 -> f.apply(t1, t2, t3, t4, t5, t6, t7, t8)); + }); + }); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with two Eithers. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Eithers are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + */ + public static class ForLazy2Either { + + private final Either ts1; + private final Function1> ts2; + + private ForLazy2Either(Either ts1, Function1> ts2) { + this.ts1 = ts1; + this.ts2 = ts2; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Eithers by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Either} + * @return an {@code Either} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Either yield(BiFunction f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).map(t2 -> f.apply(t1, t2)); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with three Eithers. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Eithers are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + */ + public static class ForLazy3Either { + + private final Either ts1; + private final Function1> ts2; + private final Function2> ts3; + + private ForLazy3Either(Either ts1, Function1> ts2, Function2> ts3) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Eithers by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Either} + * @return an {@code Either} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Either yield(Function3 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).map(t3 -> f.apply(t1, t2, t3)); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 4 Eithers. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Eithers are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + * @param the component type of the 4th Either + */ + public static class ForLazy4Either { + + private final Either ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + + private ForLazy4Either(Either ts1, Function1> ts2, Function2> ts3, Function3> ts4) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Eithers by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Either} + * @return an {@code Either} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Either yield(Function4 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).map(t4 -> f.apply(t1, t2, t3, t4)); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 5 Eithers. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Eithers are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + * @param the component type of the 4th Either + * @param the component type of the 5th Either + */ + public static class ForLazy5Either { + + private final Either ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + + private ForLazy5Either(Either ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Eithers by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Either} + * @return an {@code Either} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Either yield(Function5 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).map(t5 -> f.apply(t1, t2, t3, t4, t5)); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 6 Eithers. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Eithers are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + * @param the component type of the 4th Either + * @param the component type of the 5th Either + * @param the component type of the 6th Either + */ + public static class ForLazy6Either { + + private final Either ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + + private ForLazy6Either(Either ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Eithers by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Either} + * @return an {@code Either} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Either yield(Function6 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).map(t6 -> f.apply(t1, t2, t3, t4, t5, t6)); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 7 Eithers. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Eithers are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + * @param the component type of the 4th Either + * @param the component type of the 5th Either + * @param the component type of the 6th Either + * @param the component type of the 7th Either + */ + public static class ForLazy7Either { + + private final Either ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + + private ForLazy7Either(Either ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + this.ts7 = ts7; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Eithers by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Either} + * @return an {@code Either} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Either yield(Function7 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).map(t7 -> f.apply(t1, t2, t3, t4, t5, t6, t7)); + }); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 8 Eithers. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Eithers are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Eithers + * @param the component type of the 1st Either + * @param the component type of the 2nd Either + * @param the component type of the 3rd Either + * @param the component type of the 4th Either + * @param the component type of the 5th Either + * @param the component type of the 6th Either + * @param the component type of the 7th Either + * @param the component type of the 8th Either + */ + public static class ForLazy8Either { + + private final Either ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + private final Function7> ts8; + + private ForLazy8Either(Either ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Eithers by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Either} + * @return an {@code Either} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Either yield(Function8 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).flatMap(t7 -> { + return ts8.apply(t1, t2, t3, t4, t5, t6, t7).map(t8 -> f.apply(t1, t2, t3, t4, t5, t6, t7, t8)); + }); + }); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with two Validations. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Validations are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + */ + public static class ForLazy2Validation { + + private final Validation ts1; + private final Function1> ts2; + + private ForLazy2Validation(Validation ts1, Function1> ts2) { + this.ts1 = ts1; + this.ts2 = ts2; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Validations by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Validation} + * @return an {@code Validation} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Validation yield(BiFunction f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).map(t2 -> f.apply(t1, t2)); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with three Validations. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Validations are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + */ + public static class ForLazy3Validation { + + private final Validation ts1; + private final Function1> ts2; + private final Function2> ts3; + + private ForLazy3Validation(Validation ts1, Function1> ts2, Function2> ts3) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Validations by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Validation} + * @return an {@code Validation} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Validation yield(Function3 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).map(t3 -> f.apply(t1, t2, t3)); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 4 Validations. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Validations are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + * @param the component type of the 4th Validation + */ + public static class ForLazy4Validation { + + private final Validation ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + + private ForLazy4Validation(Validation ts1, Function1> ts2, Function2> ts3, Function3> ts4) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Validations by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Validation} + * @return an {@code Validation} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Validation yield(Function4 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).map(t4 -> f.apply(t1, t2, t3, t4)); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 5 Validations. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Validations are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + * @param the component type of the 4th Validation + * @param the component type of the 5th Validation + */ + public static class ForLazy5Validation { + + private final Validation ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + + private ForLazy5Validation(Validation ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Validations by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Validation} + * @return an {@code Validation} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Validation yield(Function5 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).map(t5 -> f.apply(t1, t2, t3, t4, t5)); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 6 Validations. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Validations are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + * @param the component type of the 4th Validation + * @param the component type of the 5th Validation + * @param the component type of the 6th Validation + */ + public static class ForLazy6Validation { + + private final Validation ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + + private ForLazy6Validation(Validation ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Validations by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Validation} + * @return an {@code Validation} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Validation yield(Function6 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).map(t6 -> f.apply(t1, t2, t3, t4, t5, t6)); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 7 Validations. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Validations are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + * @param the component type of the 4th Validation + * @param the component type of the 5th Validation + * @param the component type of the 6th Validation + * @param the component type of the 7th Validation + */ + public static class ForLazy7Validation { + + private final Validation ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + + private ForLazy7Validation(Validation ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7) { + this.ts1 = ts1; + this.ts2 = ts2; + this.ts3 = ts3; + this.ts4 = ts4; + this.ts5 = ts5; + this.ts6 = ts6; + this.ts7 = ts7; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Validations by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Validation} + * @return an {@code Validation} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Validation yield(Function7 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).map(t7 -> f.apply(t1, t2, t3, t4, t5, t6, t7)); + }); + }); + }); + }); + }); + }); + } + } + + /** + * A lazily evaluated {@code For}-comprehension with 8 Validations. + * + *

Constructed via {@code For(...)} and evaluated by calling {@code yield(...)}. + * Construction is side-effect free; underlying Validations are traversed + * only when {@code yield(...)} is invoked.

+ * + * @param the common left-hand type of all Validations + * @param the component type of the 1st Validation + * @param the component type of the 2nd Validation + * @param the component type of the 3rd Validation + * @param the component type of the 4th Validation + * @param the component type of the 5th Validation + * @param the component type of the 6th Validation + * @param the component type of the 7th Validation + * @param the component type of the 8th Validation + */ + public static class ForLazy8Validation { + + private final Validation ts1; + private final Function1> ts2; + private final Function2> ts3; + private final Function3> ts4; + private final Function4> ts5; + private final Function5> ts6; + private final Function6> ts7; + private final Function7> ts8; + + private ForLazy8Validation(Validation ts1, Function1> ts2, Function2> ts3, Function3> ts4, Function4> ts5, Function5> ts6, Function6> ts7, Function7> 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; + } + + /** + * Produces results by mapping the Cartesian product of all bound values. + * + *

Evaluation is lazy and delegated to the underlying Validations by + * composing {@code flatMap} and {@code map} chains.

+ * + * @param f a function mapping a tuple of bound values to a result + * @param the element type of the resulting {@code Validation} + * @return an {@code Validation} containing mapped results + * @throws NullPointerException if {@code f} is {@code null} + */ + public Validation yield(Function8 f) { + Objects.requireNonNull(f, "f is null"); + return ts1.flatMap(t1 -> { + return ts2.apply(t1).flatMap(t2 -> { + return ts3.apply(t1, t2).flatMap(t3 -> { + return ts4.apply(t1, t2, t3).flatMap(t4 -> { + return ts5.apply(t1, t2, t3, t4).flatMap(t5 -> { + return ts6.apply(t1, t2, t3, t4, t5).flatMap(t6 -> { + return ts7.apply(t1, t2, t3, t4, t5, t6).flatMap(t7 -> { + return ts8.apply(t1, t2, t3, t4, t5, t6, t7).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 f9e8e13d9f..e2aae86fa5 100644 --- a/vavr/src-gen/test/java/io/vavr/APITest.java +++ b/vavr/src-gen/test/java/io/vavr/APITest.java @@ -1095,6 +1095,18 @@ public void shouldIterateForOption1() { assertThat(result.get()).isEqualTo(1); } + @Test + public void shouldIterateLazyForOption1() { + final Option result = For( + Option.of(1) + ).yield(i1 -> i1); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (1 + 1)) - 2 - 1); + } + @Test public void shouldIterateForOption2() { final Option result = For( @@ -1104,6 +1116,19 @@ public void shouldIterateForOption2() { assertThat(result.get()).isEqualTo(3); } + @Test + public void shouldIterateLazyForOption2() { + final Option result = For( + Option.of(1), + (r1) -> Option.of(r1 + 2) + ).yield((i1, i2) -> i1 + i2); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (2 + 1)) - 2 - 2); + } + @Test public void shouldIterateForOption3() { final Option result = For( @@ -1114,6 +1139,20 @@ public void shouldIterateForOption3() { assertThat(result.get()).isEqualTo(6); } + @Test + public void shouldIterateLazyForOption3() { + final Option result = For( + Option.of(1), + (r1) -> Option.of(r1 + 2), + (r1, r2) -> Option.of(r1 + r2 + 3) + ).yield((i1, i2, i3) -> i1 + i2 + i3); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (3 + 1)) - 2 - 3); + } + @Test public void shouldIterateForOption4() { final Option result = For( @@ -1125,6 +1164,21 @@ public void shouldIterateForOption4() { assertThat(result.get()).isEqualTo(10); } + @Test + public void shouldIterateLazyForOption4() { + final Option result = For( + Option.of(1), + (r1) -> Option.of(r1 + 2), + (r1, r2) -> Option.of(r1 + r2 + 3), + (r1, r2, r3) -> Option.of(r1 + r2 + r3 + 4) + ).yield((i1, i2, i3, i4) -> i1 + i2 + i3 + i4); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (4 + 1)) - 2 - 4); + } + @Test public void shouldIterateForOption5() { final Option result = For( @@ -1137,6 +1191,22 @@ public void shouldIterateForOption5() { assertThat(result.get()).isEqualTo(15); } + @Test + public void shouldIterateLazyForOption5() { + final Option result = For( + Option.of(1), + (r1) -> Option.of(r1 + 2), + (r1, r2) -> Option.of(r1 + r2 + 3), + (r1, r2, r3) -> Option.of(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Option.of(r1 + r2 + r3 + r4 + 5) + ).yield((i1, i2, i3, i4, i5) -> i1 + i2 + i3 + i4 + i5); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (5 + 1)) - 2 - 5); + } + @Test public void shouldIterateForOption6() { final Option result = For( @@ -1150,6 +1220,23 @@ public void shouldIterateForOption6() { assertThat(result.get()).isEqualTo(21); } + @Test + public void shouldIterateLazyForOption6() { + final Option result = For( + Option.of(1), + (r1) -> Option.of(r1 + 2), + (r1, r2) -> Option.of(r1 + r2 + 3), + (r1, r2, r3) -> Option.of(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Option.of(r1 + r2 + r3 + r4 + 5), + (r1, r2, r3, r4, r5) -> Option.of(r1 + r2 + r3 + r4 + r5 + 6) + ).yield((i1, i2, i3, i4, i5, i6) -> i1 + i2 + i3 + i4 + i5 + i6); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (6 + 1)) - 2 - 6); + } + @Test public void shouldIterateForOption7() { final Option result = For( @@ -1164,6 +1251,24 @@ public void shouldIterateForOption7() { assertThat(result.get()).isEqualTo(28); } + @Test + public void shouldIterateLazyForOption7() { + final Option result = For( + Option.of(1), + (r1) -> Option.of(r1 + 2), + (r1, r2) -> Option.of(r1 + r2 + 3), + (r1, r2, r3) -> Option.of(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Option.of(r1 + r2 + r3 + r4 + 5), + (r1, r2, r3, r4, r5) -> Option.of(r1 + r2 + r3 + r4 + r5 + 6), + (r1, r2, r3, r4, r5, r6) -> Option.of(r1 + r2 + r3 + r4 + r5 + r6 + 7) + ).yield((i1, i2, i3, i4, i5, i6, i7) -> i1 + i2 + i3 + i4 + i5 + i6 + i7); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (7 + 1)) - 2 - 7); + } + @Test public void shouldIterateForOption8() { final Option result = For( @@ -1179,6 +1284,25 @@ public void shouldIterateForOption8() { assertThat(result.get()).isEqualTo(36); } + @Test + public void shouldIterateLazyForOption8() { + final Option result = For( + Option.of(1), + (r1) -> Option.of(r1 + 2), + (r1, r2) -> Option.of(r1 + r2 + 3), + (r1, r2, r3) -> Option.of(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Option.of(r1 + r2 + r3 + r4 + 5), + (r1, r2, r3, r4, r5) -> Option.of(r1 + r2 + r3 + r4 + r5 + 6), + (r1, r2, r3, r4, r5, r6) -> Option.of(r1 + r2 + r3 + r4 + r5 + r6 + 7), + (r1, r2, r3, r4, r5, r6, r7) -> Option.of(r1 + r2 + r3 + r4 + r5 + r6 + r7 + 8) + ).yield((i1, i2, i3, i4, i5, i6, i7, i8) -> i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (8 + 1)) - 2 - 8); + } + @Test public void shouldIterateForEither1() { final Either result = For( @@ -1187,6 +1311,18 @@ public void shouldIterateForEither1() { assertThat(result.get()).isEqualTo(1); } + @Test + public void shouldIterateLazyForEither1() { + final Either result = For( + Either.right(1) + ).yield(i1 -> i1); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (1 + 1)) - 2 - 1); + } + @Test public void shouldIterateForEither2() { final Either result = For( @@ -1196,6 +1332,19 @@ public void shouldIterateForEither2() { assertThat(result.get()).isEqualTo(3); } + @Test + public void shouldIterateLazyForEither2() { + final Either result = For( + Either.right(1), + (r1) -> Either.right(r1 + 2) + ).yield((i1, i2) -> i1 + i2); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (2 + 1)) - 2 - 2); + } + @Test public void shouldIterateForEither3() { final Either result = For( @@ -1206,6 +1355,20 @@ public void shouldIterateForEither3() { assertThat(result.get()).isEqualTo(6); } + @Test + public void shouldIterateLazyForEither3() { + final Either result = For( + Either.right(1), + (r1) -> Either.right(r1 + 2), + (r1, r2) -> Either.right(r1 + r2 + 3) + ).yield((i1, i2, i3) -> i1 + i2 + i3); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (3 + 1)) - 2 - 3); + } + @Test public void shouldIterateForEither4() { final Either result = For( @@ -1217,6 +1380,21 @@ public void shouldIterateForEither4() { assertThat(result.get()).isEqualTo(10); } + @Test + public void shouldIterateLazyForEither4() { + final Either result = For( + Either.right(1), + (r1) -> Either.right(r1 + 2), + (r1, r2) -> Either.right(r1 + r2 + 3), + (r1, r2, r3) -> Either.right(r1 + r2 + r3 + 4) + ).yield((i1, i2, i3, i4) -> i1 + i2 + i3 + i4); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (4 + 1)) - 2 - 4); + } + @Test public void shouldIterateForEither5() { final Either result = For( @@ -1229,6 +1407,22 @@ public void shouldIterateForEither5() { assertThat(result.get()).isEqualTo(15); } + @Test + public void shouldIterateLazyForEither5() { + final Either result = For( + Either.right(1), + (r1) -> Either.right(r1 + 2), + (r1, r2) -> Either.right(r1 + r2 + 3), + (r1, r2, r3) -> Either.right(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Either.right(r1 + r2 + r3 + r4 + 5) + ).yield((i1, i2, i3, i4, i5) -> i1 + i2 + i3 + i4 + i5); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (5 + 1)) - 2 - 5); + } + @Test public void shouldIterateForEither6() { final Either result = For( @@ -1242,6 +1436,23 @@ public void shouldIterateForEither6() { assertThat(result.get()).isEqualTo(21); } + @Test + public void shouldIterateLazyForEither6() { + final Either result = For( + Either.right(1), + (r1) -> Either.right(r1 + 2), + (r1, r2) -> Either.right(r1 + r2 + 3), + (r1, r2, r3) -> Either.right(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Either.right(r1 + r2 + r3 + r4 + 5), + (r1, r2, r3, r4, r5) -> Either.right(r1 + r2 + r3 + r4 + r5 + 6) + ).yield((i1, i2, i3, i4, i5, i6) -> i1 + i2 + i3 + i4 + i5 + i6); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (6 + 1)) - 2 - 6); + } + @Test public void shouldIterateForEither7() { final Either result = For( @@ -1256,6 +1467,24 @@ public void shouldIterateForEither7() { assertThat(result.get()).isEqualTo(28); } + @Test + public void shouldIterateLazyForEither7() { + final Either result = For( + Either.right(1), + (r1) -> Either.right(r1 + 2), + (r1, r2) -> Either.right(r1 + r2 + 3), + (r1, r2, r3) -> Either.right(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Either.right(r1 + r2 + r3 + r4 + 5), + (r1, r2, r3, r4, r5) -> Either.right(r1 + r2 + r3 + r4 + r5 + 6), + (r1, r2, r3, r4, r5, r6) -> Either.right(r1 + r2 + r3 + r4 + r5 + r6 + 7) + ).yield((i1, i2, i3, i4, i5, i6, i7) -> i1 + i2 + i3 + i4 + i5 + i6 + i7); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (7 + 1)) - 2 - 7); + } + @Test public void shouldIterateForEither8() { final Either result = For( @@ -1271,6 +1500,25 @@ public void shouldIterateForEither8() { assertThat(result.get()).isEqualTo(36); } + @Test + public void shouldIterateLazyForEither8() { + final Either result = For( + Either.right(1), + (r1) -> Either.right(r1 + 2), + (r1, r2) -> Either.right(r1 + r2 + 3), + (r1, r2, r3) -> Either.right(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Either.right(r1 + r2 + r3 + r4 + 5), + (r1, r2, r3, r4, r5) -> Either.right(r1 + r2 + r3 + r4 + r5 + 6), + (r1, r2, r3, r4, r5, r6) -> Either.right(r1 + r2 + r3 + r4 + r5 + r6 + 7), + (r1, r2, r3, r4, r5, r6, r7) -> Either.right(r1 + r2 + r3 + r4 + r5 + r6 + r7 + 8) + ).yield((i1, i2, i3, i4, i5, i6, i7, i8) -> i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (8 + 1)) - 2 - 8); + } + @Test public void shouldIterateForValidation1() { final Validation result = For( @@ -1279,6 +1527,18 @@ public void shouldIterateForValidation1() { assertThat(result.get()).isEqualTo(1); } + @Test + public void shouldIterateLazyForValidation1() { + final Validation result = For( + Validation.valid(1) + ).yield(i1 -> i1); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (1 + 1)) - 2 - 1); + } + @Test public void shouldIterateForValidation2() { final Validation result = For( @@ -1288,6 +1548,19 @@ public void shouldIterateForValidation2() { assertThat(result.get()).isEqualTo(3); } + @Test + public void shouldIterateLazyForValidation2() { + final Validation result = For( + Validation.valid(1), + (r1) -> Validation.valid(r1 + 2) + ).yield((i1, i2) -> i1 + i2); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (2 + 1)) - 2 - 2); + } + @Test public void shouldIterateForValidation3() { final Validation result = For( @@ -1298,6 +1571,20 @@ public void shouldIterateForValidation3() { assertThat(result.get()).isEqualTo(6); } + @Test + public void shouldIterateLazyForValidation3() { + final Validation result = For( + Validation.valid(1), + (r1) -> Validation.valid(r1 + 2), + (r1, r2) -> Validation.valid(r1 + r2 + 3) + ).yield((i1, i2, i3) -> i1 + i2 + i3); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (3 + 1)) - 2 - 3); + } + @Test public void shouldIterateForValidation4() { final Validation result = For( @@ -1309,6 +1596,21 @@ public void shouldIterateForValidation4() { assertThat(result.get()).isEqualTo(10); } + @Test + public void shouldIterateLazyForValidation4() { + final Validation result = For( + Validation.valid(1), + (r1) -> Validation.valid(r1 + 2), + (r1, r2) -> Validation.valid(r1 + r2 + 3), + (r1, r2, r3) -> Validation.valid(r1 + r2 + r3 + 4) + ).yield((i1, i2, i3, i4) -> i1 + i2 + i3 + i4); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (4 + 1)) - 2 - 4); + } + @Test public void shouldIterateForValidation5() { final Validation result = For( @@ -1321,6 +1623,22 @@ public void shouldIterateForValidation5() { assertThat(result.get()).isEqualTo(15); } + @Test + public void shouldIterateLazyForValidation5() { + final Validation result = For( + Validation.valid(1), + (r1) -> Validation.valid(r1 + 2), + (r1, r2) -> Validation.valid(r1 + r2 + 3), + (r1, r2, r3) -> Validation.valid(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Validation.valid(r1 + r2 + r3 + r4 + 5) + ).yield((i1, i2, i3, i4, i5) -> i1 + i2 + i3 + i4 + i5); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (5 + 1)) - 2 - 5); + } + @Test public void shouldIterateForValidation6() { final Validation result = For( @@ -1334,6 +1652,23 @@ public void shouldIterateForValidation6() { assertThat(result.get()).isEqualTo(21); } + @Test + public void shouldIterateLazyForValidation6() { + final Validation result = For( + Validation.valid(1), + (r1) -> Validation.valid(r1 + 2), + (r1, r2) -> Validation.valid(r1 + r2 + 3), + (r1, r2, r3) -> Validation.valid(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Validation.valid(r1 + r2 + r3 + r4 + 5), + (r1, r2, r3, r4, r5) -> Validation.valid(r1 + r2 + r3 + r4 + r5 + 6) + ).yield((i1, i2, i3, i4, i5, i6) -> i1 + i2 + i3 + i4 + i5 + i6); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (6 + 1)) - 2 - 6); + } + @Test public void shouldIterateForValidation7() { final Validation result = For( @@ -1348,6 +1683,24 @@ public void shouldIterateForValidation7() { assertThat(result.get()).isEqualTo(28); } + @Test + public void shouldIterateLazyForValidation7() { + final Validation result = For( + Validation.valid(1), + (r1) -> Validation.valid(r1 + 2), + (r1, r2) -> Validation.valid(r1 + r2 + 3), + (r1, r2, r3) -> Validation.valid(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Validation.valid(r1 + r2 + r3 + r4 + 5), + (r1, r2, r3, r4, r5) -> Validation.valid(r1 + r2 + r3 + r4 + r5 + 6), + (r1, r2, r3, r4, r5, r6) -> Validation.valid(r1 + r2 + r3 + r4 + r5 + r6 + 7) + ).yield((i1, i2, i3, i4, i5, i6, i7) -> i1 + i2 + i3 + i4 + i5 + i6 + i7); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (7 + 1)) - 2 - 7); + } + @Test public void shouldIterateForValidation8() { final Validation result = For( @@ -1363,6 +1716,25 @@ public void shouldIterateForValidation8() { assertThat(result.get()).isEqualTo(36); } + @Test + public void shouldIterateLazyForValidation8() { + final Validation result = For( + Validation.valid(1), + (r1) -> Validation.valid(r1 + 2), + (r1, r2) -> Validation.valid(r1 + r2 + 3), + (r1, r2, r3) -> Validation.valid(r1 + r2 + r3 + 4), + (r1, r2, r3, r4) -> Validation.valid(r1 + r2 + r3 + r4 + 5), + (r1, r2, r3, r4, r5) -> Validation.valid(r1 + r2 + r3 + r4 + r5 + 6), + (r1, r2, r3, r4, r5, r6) -> Validation.valid(r1 + r2 + r3 + r4 + r5 + r6 + 7), + (r1, r2, r3, r4, r5, r6, r7) -> Validation.valid(r1 + r2 + r3 + r4 + r5 + r6 + r7 + 8) + ).yield((i1, i2, i3, i4, i5, i6, i7, i8) -> i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8); + + // Each step builds on the sum of all previous results plus its index + // This forms a sequence rₙ = 2ⁿ - 1, and the yield sums all rᵢ. + // Hence total = Σ(2ⁱ - 1) for i = 1..n = (2ⁿ⁺¹ - 2) - n + assertThat(result.get()).isEqualTo((1 << (8 + 1)) - 2 - 8); + } + @Test public void shouldIterateForFuture1() { final Future result = For(