@@ -743,6 +743,133 @@ def generateMainClasses(): Unit = {
743743 """
744744 }
745745
746+ def genLazyFor (im : ImportManager , packageName : String , className : String ): String = {
747+ xs """
748+ ${
749+ monadicTypesFor
750+ .filterNot(_ == " Iterable" )
751+ .gen(mtype => (2 to N ).gen(i => {
752+ val forClassName = s " ForLazy $i$mtype"
753+ val isComplex = monadicTypesThatNeedParameter.contains(mtype)
754+ val parameterInset = if (isComplex) " L, " else " "
755+ val generics = parameterInset + (1 to i).gen(j => s " T $j" )(" , " )
756+
757+ val params = (1 to i).gen { j =>
758+ if (j == 1 )
759+ s " $mtype< ${parameterInset}T1> ts1 "
760+ else {
761+ val inputTypes = (1 until j).gen(k => s " T $k" )(" , " )
762+ s " Function ${j - 1 }< $inputTypes, $mtype< ${parameterInset}T $j>> ts $j"
763+ }
764+ }(" , " )
765+
766+ val ctorArgs = (1 to i).gen(j => s " ts $j" )(" , " )
767+
768+ xs """
769+ / $javadoc
770+ * Creates a {@code For}-comprehension of ${i.numerus(mtype)}.
771+ ${(0 to i).gen(j => if (j == 0 ) " *" else s " * @param ts $j the ${j.ordinal} $mtype" )(" \n " )}
772+ ${if (isComplex) s " * @param <L> left-hand type of all ${mtype}s \n " else " " }
773+ ${(1 to i).gen(j => s " * @param <T $j> component type of the ${j.ordinal} $mtype" )(" \n " )}
774+ * @return a new {@code For}-comprehension of arity $i
775+ */
776+ public static < $generics> $forClassName< $generics> For( $params) {
777+ ${(1 to i).gen(j => xs """ $Objects.requireNonNull(ts $j, "ts $j is null"); """ )(" \n " )}
778+ return new $forClassName<>( $ctorArgs);
779+ }
780+ """
781+ })(" \n\n " ))(" \n\n " )
782+ }
783+
784+ ${
785+ monadicTypesFor
786+ .filterNot(_ == " Iterable" )
787+ .gen(mtype => (2 to N ).gen(i => {
788+ val rtype = mtype
789+ val forClassName = s " ForLazy $i$mtype"
790+ val parameterInset = if (monadicTypesThatNeedParameter.contains(mtype)) " L, " else " "
791+ val generics = parameterInset + (1 to i).gen(j => s " T $j" )(" , " )
792+ val functionType = i match {
793+ case 2 => BiFunctionType
794+ case _ => s " Function $i"
795+ }
796+ val args = (1 to i).gen(j => s " ? super T $j" )(" , " )
797+
798+ val fields = (1 to i).gen { j =>
799+ if (j == 1 )
800+ s " private final $mtype< ${parameterInset}T1> ts1; "
801+ else {
802+ val inputTypes = (1 until j).gen(k => s " T $k" )(" , " )
803+ s " private final Function ${j - 1 }< $inputTypes, $mtype< ${parameterInset}T $j>> ts $j; "
804+ }
805+ }(" \n " )
806+
807+ val ctorParams = (1 to i).gen { j =>
808+ if (j == 1 )
809+ s " $mtype< ${parameterInset}T1> ts1 "
810+ else {
811+ val inputTypes = (1 until j).gen(k => s " T $k" )(" , " )
812+ s " Function ${j - 1 }< $inputTypes, $mtype< ${parameterInset}T $j>> ts $j"
813+ }
814+ }(" , " )
815+
816+ val assignments = (1 to i).gen(j => s " this.ts $j = ts $j; " )(" \n " )
817+
818+ val yieldBody = {
819+ def nestedLambda (j : Int ): String = {
820+ val base = " " * 3
821+ val indent = " " * j
822+ if (j == i) {
823+ val argsList = (1 to i).map(k => s " t $k" ).mkString(" , " )
824+ val inputArgs = (1 until i).map(k => s " t $k" ).mkString(" , " )
825+ s " ts $i.apply( $inputArgs).map(t $i -> f.apply( $argsList)) "
826+ } else if (j == 1 ) {
827+ s " ts1.flatMap(t1 -> { \n " +
828+ s " ${base}${indent} return ${nestedLambda(j + 1 )}; \n " +
829+ s " ${base}${indent}}) "
830+ } else {
831+ val inputArgs = (1 until j).map(k => s " t $k" ).mkString(" , " )
832+ s " ts $j.apply( $inputArgs).flatMap(t $j -> { \n " +
833+ s " ${base}${indent} return ${nestedLambda(j + 1 )}; \n " +
834+ s " ${base}${indent}}) "
835+ }
836+ }
837+
838+ nestedLambda(1 )
839+ }
840+
841+ xs """
842+ / $javadoc
843+ * For-comprehension with ${i.numerus(mtype)}.
844+ */
845+ public static class $forClassName< $generics> {
846+
847+ $fields
848+
849+ private $forClassName( $ctorParams) {
850+ $assignments
851+ }
852+
853+ / $javadoc
854+ * Yields a result for elements of the cross-product of the underlying ${i.plural(mtype)}.
855+ *
856+ * @param f a function that maps an element of the cross-product to a result
857+ * @param <R> type of the resulting {@code $rtype} elements
858+ * @return an {@code $rtype} of mapped results
859+ */
860+ public <R> $rtype< ${parameterInset}R> yield( $functionType< $args, ? extends R> f) {
861+ $Objects.requireNonNull(f, "f is null");
862+
863+ return $yieldBody;
864+ }
865+ }
866+ """
867+ })(" \n\n " ))(" \n\n " )
868+ }
869+ """
870+ }
871+
872+
746873 def genFor (im : ImportManager , packageName : String , className : String ): String = {
747874 xs """
748875 //
@@ -1440,6 +1567,8 @@ def generateMainClasses(): Unit = {
14401567
14411568 ${genFor(im, packageName, className)}
14421569
1570+ ${genLazyFor(im, packageName, className)}
1571+
14431572 ${genMatch(im, packageName, className)}
14441573 }
14451574 """
0 commit comments