From c6aaaafd4d0fc505c400219932cff6eeb9afdd33 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 23 May 2019 18:08:32 +0200 Subject: [PATCH 01/14] Add TupledFunction to abstract over function arities Add tests --- .../dotty/tools/dotc/core/Definitions.scala | 11 +- .../dotty/tools/dotc/typer/Implicits.scala | 23 +++- library/src-3.x/dotty/DottyPredef.scala | 8 ++ library/src-3.x/scala/TupledFunction.scala | 16 +++ .../scala/internal/TupledFunction.scala | 119 ++++++++++++++++++ tests/neg/tupled-function-instances.scala | 82 ++++++++++++ tests/pos/tupled-function-instances.scala | 31 +++++ tests/run/tupled-function-andThen.check | 4 + tests/run/tupled-function-andThen.scala | 27 ++++ tests/run/tupled-function-compose.check | 4 + tests/run/tupled-function-compose.scala | 27 ++++ .../tupled-function-extension-method.check | 5 + .../tupled-function-extension-method.scala | 32 +++++ tests/run/tupled-function-tupled.check | 3 + tests/run/tupled-function-tupled.scala | 17 +++ tests/run/tupled-function.check | 26 ++++ tests/run/tupled-function.scala | 110 ++++++++++++++++ 17 files changed, 542 insertions(+), 3 deletions(-) create mode 100644 library/src-3.x/scala/TupledFunction.scala create mode 100644 library/src-3.x/scala/internal/TupledFunction.scala create mode 100644 tests/neg/tupled-function-instances.scala create mode 100644 tests/pos/tupled-function-instances.scala create mode 100644 tests/run/tupled-function-andThen.check create mode 100644 tests/run/tupled-function-andThen.scala create mode 100644 tests/run/tupled-function-compose.check create mode 100644 tests/run/tupled-function-compose.scala create mode 100644 tests/run/tupled-function-extension-method.check create mode 100644 tests/run/tupled-function-extension-method.scala create mode 100644 tests/run/tupled-function-tupled.check create mode 100644 tests/run/tupled-function-tupled.scala create mode 100644 tests/run/tupled-function.check create mode 100644 tests/run/tupled-function.scala diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 27d34b00cf9f..a70c58dacbcf 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -24,7 +24,7 @@ object Definitions { * The limit 22 is chosen for Scala2x interop. It could be something * else without affecting the set of programs that can be compiled. */ - val MaxImplementedFunctionArity: Int = 22 + val MaxImplementedFunctionArity: Int = MaxTupleArity } /** A class defining symbols and types of standard definitions @@ -795,6 +795,13 @@ class Definitions { def TupleXXL_apply(implicit ctx: Context): Symbol = TupleXXLModule.info.member(nme.apply).requiredSymbol("method", nme.apply, TupleXXLModule)(_.info.isVarArgsMethod) + lazy val TupledFunctionTypeRef: TypeRef = ctx.requiredClassRef("scala.TupledFunction") + def TupleFunctionClass(implicit ctx: Context): ClassSymbol = TupledFunctionTypeRef.symbol.asClass + + lazy val InternalTupledFunctionTypeRef: TypeRef = ctx.requiredClassRef("scala.internal.TupledFunction") + def InternalTupleFunctionClass(implicit ctx: Context): ClassSymbol = InternalTupledFunctionTypeRef.symbol.asClass + def InternalTupleFunctionModule(implicit ctx: Context): Symbol = ctx.requiredModule("scala.internal.TupledFunction") + // Annotation base classes lazy val AnnotationType: TypeRef = ctx.requiredClassRef("scala.annotation.Annotation") def AnnotationClass(implicit ctx: Context): ClassSymbol = AnnotationType.symbol.asClass @@ -1187,7 +1194,7 @@ class Definitions { def tupleType(elems: List[Type]): Type = { val arity = elems.length - if (arity <= MaxTupleArity && TupleType(arity) != null) TupleType(arity).appliedTo(elems) + if (0 < arity && arity <= MaxTupleArity && TupleType(arity) != null) TupleType(arity).appliedTo(elems) else TypeOps.nestedPairs(elems) } diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 72d97dc4bb28..bac22aa99341 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -709,6 +709,26 @@ trait Implicits { self: Typer => if (ctx.inInlineMethod || enclosingInlineds.nonEmpty) ref(defn.TastyReflection_macroContext) else EmptyTree + def synthesizedTupleFunction(formal: Type): Tree = { + formal match { + case AppliedType(_, fun :: args :: ret :: Nil) if defn.isFunctionType(fun) => + val funTypes = fun.dropDependentRefinement.dealias.argInfos + if (defn.tupleType(funTypes.init) =:= args && funTypes.last =:= ret) { + val arity = funTypes.size - 1 + if (defn.isErasedFunctionType(fun)) + EmptyTree // TODO support? + else if (defn.isImplicitFunctionType(fun)) + EmptyTree // TODO support + else if (arity <= Definitions.MaxImplementedFunctionArity) + ref(defn.InternalTupleFunctionModule).select(s"tupledFunction$arity".toTermName).appliedToTypes(funTypes) + else + ref(defn.InternalTupleFunctionModule).select("tupledFunctionXXL".toTermName).appliedToTypes(fun :: args :: ret :: Nil) + } else EmptyTree + case _ => + EmptyTree + } + } + /** If `formal` is of the form Eql[T, U], try to synthesize an * `Eql.eqlAny[T, U]` as solution. */ @@ -828,7 +848,8 @@ trait Implicits { self: Typer => trySpecialCase(defn.GenericClass, synthesizedGeneric, trySpecialCase(defn.TastyReflectionClass, synthesizedTastyContext, trySpecialCase(defn.EqlClass, synthesizedEq, - trySpecialCase(defn.ValueOfClass, synthesizedValueOf, failed)))))) + trySpecialCase(defn.TupleFunctionClass, synthesizedTupleFunction, + trySpecialCase(defn.ValueOfClass, synthesizedValueOf, failed))))))) } } diff --git a/library/src-3.x/dotty/DottyPredef.scala b/library/src-3.x/dotty/DottyPredef.scala index 49f275b0c98a..6fc437404fc3 100644 --- a/library/src-3.x/dotty/DottyPredef.scala +++ b/library/src-3.x/dotty/DottyPredef.scala @@ -37,4 +37,12 @@ object DottyPredef { } inline def the[T] given (x: T): x.type = x + + /** Creates a tupled version of this function: instead of N arguments, + * it accepts a single [[scala.Tuple]] argument. + */ + def (f: F) tupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args, R]): Args => R = { + x => tf.applyFunctionTo(f, x) + } + } diff --git a/library/src-3.x/scala/TupledFunction.scala b/library/src-3.x/scala/TupledFunction.scala new file mode 100644 index 000000000000..71c3a3796892 --- /dev/null +++ b/library/src-3.x/scala/TupledFunction.scala @@ -0,0 +1,16 @@ +package scala + +import scala.annotation.implicitNotFound + +@implicitNotFound("${F} cannot be tupled as ${Args} => ${R}") +trait TupledFunction[F, Args <: Tuple, R] { + def applyFunctionTo(f: F, args: Args): R +} + +object TupledFunction { + + /** Apply this function to with each element of the tuple as a parameter */ + def (f: F) apply[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, Args, R]): R = + tf.applyFunctionTo(f, args) + +} diff --git a/library/src-3.x/scala/internal/TupledFunction.scala b/library/src-3.x/scala/internal/TupledFunction.scala new file mode 100644 index 000000000000..11b3eddfd7ef --- /dev/null +++ b/library/src-3.x/scala/internal/TupledFunction.scala @@ -0,0 +1,119 @@ +package scala.internal + +object TupledFunction { + + def tupledFunction0[R]: TupledFunction[() => R, Unit, R] = new TupledFunction { + def applyFunctionTo(f: () => R, args: Unit): R = f() + } + + def tupledFunction1[T1, R]: TupledFunction[T1 => R, Tuple1[T1], R] = new TupledFunction { + def applyFunctionTo(f: T1 => R, args: Tuple1[T1]): R = f(args._1) + } + + def tupledFunction2[T1, T2, R]: TupledFunction[(T1, T2) => R, Tuple2[T1, T2], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2) => R, args: Tuple2[T1, T2]): R = f(args._1, args._2) + } + + def tupledFunction3[T1, T2, T3, R]: TupledFunction[(T1, T2, T3) => R, Tuple3[T1, T2, T3], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3) => R, args: Tuple3[T1, T2, T3]): R = f(args._1, args._2, args._3) + } + + def tupledFunction4[T1, T2, T3, T4, R]: TupledFunction[(T1, T2, T3, T4) => R, Tuple4[T1, T2, T3, T4], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4) => R, args: Tuple4[T1, T2, T3, T4]): R = f(args._1, args._2, args._3, args._4) + } + + def tupledFunction5[T1, T2, T3, T4, T5, R]: TupledFunction[(T1, T2, T3, T4, T5) => R, Tuple5[T1, T2, T3, T4, T5], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5) => R, args: Tuple5[T1, T2, T3, T4, T5]): R = f(args._1, args._2, args._3, args._4, args._5) + } + + def tupledFunction6[T1, T2, T3, T4, T5, T6, R]: TupledFunction[(T1, T2, T3, T4, T5, T6) => R, Tuple6[T1, T2, T3, T4, T5, T6], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6) => R, args: Tuple6[T1, T2, T3, T4, T5, T6]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6) + } + + def tupledFunction7[T1, T2, T3, T4, T5, T6, T7, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7) => R, Tuple7[T1, T2, T3, T4, T5, T6, T7], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7) => R, args: Tuple7[T1, T2, T3, T4, T5, T6, T7]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7) + } + + def tupledFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8) => R, Tuple8[T1, T2, T3, T4, T5, T6, T7, T8], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8) => R, args: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8) + } + + def tupledFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9) => R, Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9) => R, args: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9) + } + + def tupledFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => R, Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => R, args: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10) + } + + def tupledFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) => R, Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) => R, args: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11) + } + + def tupledFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) => R, Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) => R, args: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12) + } + + def tupledFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) => R, Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) => R, args: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13) + } + + def tupledFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) => R, Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) => R, args: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14) + } + + def tupledFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) => R, Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) => R, args: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15) + } + + def tupledFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) => R, Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) => R, args: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16) + } + + def tupledFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) => R, Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) => R, args: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17) + } + + def tupledFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) => R, Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) => R, args: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17, args._18) + } + + def tupledFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) => R, Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) => R, args: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17, args._18, args._19) + } + + def tupledFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) => R, Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) => R, args: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17, args._18, args._19, args._20) + } + + def tupledFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) => R, Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) => R, args: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17, args._18, args._19, args._20, args._21) + } + + def tupledFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) => R, Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22], R] = new TupledFunction { + def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) => R, args: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]): R = + f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17, args._18, args._19, args._20, args._21, args._22) + } + + def tupledFunctionXXL[F, Args <: Tuple, R]: TupledFunction[F, Args, R] = new TupledFunction { + def applyFunctionTo(f: F, args: Args): R = + f.asInstanceOf[FunctionXXL].apply(args.asInstanceOf[TupleXXL].elems).asInstanceOf[R] + } + +} diff --git a/tests/neg/tupled-function-instances.scala b/tests/neg/tupled-function-instances.scala new file mode 100644 index 000000000000..ab120ca95d9f --- /dev/null +++ b/tests/neg/tupled-function-instances.scala @@ -0,0 +1,82 @@ +object Test { + def main(args: Array[String]): Unit = { + type R + the[TupledFunction[given 1 => R, Tuple1[1], R]] // error + the[TupledFunction[given (1, 2) => R, (1, 2), R]] // error + the[TupledFunction[given (1, 2, 3) => R, (1, 2, 3), R]] // error + the[TupledFunction[given (1, 2, 3, 4) => R, (1, 2, 3, 4), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5) => R, (1, 2, 3, 4, 5), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6) => R, (1, 2, 3, 4, 5, 6), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7) => R, (1, 2, 3, 4, 5, 6, 7), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8) => R, (1, 2, 3, 4, 5, 6, 7, 8), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), R]] // error + the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), R]] // error + + the[TupledFunction[erased 1 => R, Tuple1[1], R]] // error + the[TupledFunction[erased (1, 2) => R, (1, 2), R]] // error + the[TupledFunction[erased (1, 2, 3) => R, (1, 2, 3), R]] // error + the[TupledFunction[erased (1, 2, 3, 4) => R, (1, 2, 3, 4), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5) => R, (1, 2, 3, 4, 5), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6) => R, (1, 2, 3, 4, 5, 6), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7) => R, (1, 2, 3, 4, 5, 6, 7), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8) => R, (1, 2, 3, 4, 5, 6, 7, 8), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), R]] // error + the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), R]] // error + + the[TupledFunction[given erased 1 => R, Tuple1[1], R]] // error + the[TupledFunction[given erased (1, 2) => R, (1, 2), R]] // error + the[TupledFunction[given erased (1, 2, 3) => R, (1, 2, 3), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4) => R, (1, 2, 3, 4), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5) => R, (1, 2, 3, 4, 5), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6) => R, (1, 2, 3, 4, 5, 6), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7) => R, (1, 2, 3, 4, 5, 6, 7), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8) => R, (1, 2, 3, 4, 5, 6, 7, 8), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), R]] // error + the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), R]] // error + } +} \ No newline at end of file diff --git a/tests/pos/tupled-function-instances.scala b/tests/pos/tupled-function-instances.scala new file mode 100644 index 000000000000..8301788e97d8 --- /dev/null +++ b/tests/pos/tupled-function-instances.scala @@ -0,0 +1,31 @@ +object Test { + def main(args: Array[String]): Unit = { + type R + the[TupledFunction[() => R, Unit, R]] + the[TupledFunction[1 => R, Tuple1[1], R]] + the[TupledFunction[(1, 2) => R, (1, 2), R]] + the[TupledFunction[(1, 2, 3) => R, (1, 2, 3), R]] + the[TupledFunction[(1, 2, 3, 4) => R, (1, 2, 3, 4), R]] + the[TupledFunction[(1, 2, 3, 4, 5) => R, (1, 2, 3, 4, 5), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6) => R, (1, 2, 3, 4, 5, 6), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7) => R, (1, 2, 3, 4, 5, 6, 7), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8) => R, (1, 2, 3, 4, 5, 6, 7, 8), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), R]] + the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), R]] + } +} \ No newline at end of file diff --git a/tests/run/tupled-function-andThen.check b/tests/run/tupled-function-andThen.check new file mode 100644 index 000000000000..12ff3f4e95fd --- /dev/null +++ b/tests/run/tupled-function-andThen.check @@ -0,0 +1,4 @@ +6 +(2,7) +18 +(6,12,18,24,30,36,42,48,54,60,66,72,78,84,90,96,102,108,114,120,126,132,138,144,150) diff --git a/tests/run/tupled-function-andThen.scala b/tests/run/tupled-function-andThen.scala new file mode 100644 index 000000000000..72c3cf62fdb0 --- /dev/null +++ b/tests/run/tupled-function-andThen.scala @@ -0,0 +1,27 @@ +object Test { + def main(args: Array[String]): Unit = { + + val f1 = (x1: Int, x2: Int) => (x1, x2, x1 + x2) + val g1 = (x1: Int, x2: Int, x3: Int) => x1 + x2 + x3 + val h1 = f1.tupled.andThen(g1.tupled) + println(h1(1, 2)) + + val f2 = (x1: Int, x2: Int) => (1, x1, x2, x1 + x2, x1 * x2) + val g2 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int) => (x1 + x2, x3 + x4 + x5) + val h2 = f2.tupled.andThen(g2.tupled) + println(h2(1, 2)) + + val h3 = h2.andThen(h1) + println(h3(1, 2)) + + val f25 = + (x0: Int, x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int) => + (2 * x0, 2 * x1, 2 * x2, 2 * x3, 2 * x4, 2 * x5, 2 * x6, 2 * x7, 2 * x8, 2 * x9, 2 * x10, 2 * x11, 2 * x12, 2 * x13, 2 * x14, 2 * x15, 2 * x16, 2 * x17, 2 * x18, 2 * x19, 2 * x20, 2 * x21, 2 * x22, 2 * x23, 2 * x24) + val g25 = + (x0: Int, x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int) => + (3 * x0, 3 * x1, 3 * x2, 3 * x3, 3 * x4, 3 * x5, 3 * x6, 3 * x7, 3 * x8, 3 * x9, 3 * x10, 3 * x11, 3 * x12, 3 * x13, 3 * x14, 3 * x15, 3 * x16, 3 * x17, 3 * x18, 3 * x19, 3 * x20, 3 * x21, 3 * x22, 3 * x23, 3 * x24) + val h25 = f25.tupled.andThen(g25.tupled) + println(h25(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)) + + } +} diff --git a/tests/run/tupled-function-compose.check b/tests/run/tupled-function-compose.check new file mode 100644 index 000000000000..12ff3f4e95fd --- /dev/null +++ b/tests/run/tupled-function-compose.check @@ -0,0 +1,4 @@ +6 +(2,7) +18 +(6,12,18,24,30,36,42,48,54,60,66,72,78,84,90,96,102,108,114,120,126,132,138,144,150) diff --git a/tests/run/tupled-function-compose.scala b/tests/run/tupled-function-compose.scala new file mode 100644 index 000000000000..6c22b3ba8327 --- /dev/null +++ b/tests/run/tupled-function-compose.scala @@ -0,0 +1,27 @@ +object Test { + def main(args: Array[String]): Unit = { + + val f1 = (x1: Int, x2: Int) => (x1, x2, x1 + x2) + val g1 = (x1: Int, x2: Int, x3: Int) => x1 + x2 + x3 + val h1 = g1.tupled.compose(f1.tupled) + println(h1(1, 2)) + + val f2 = (x1: Int, x2: Int) => (1, x1, x2, x1 + x2, x1 * x2) + val g2 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int) => (x1 + x2, x3 + x4 + x5) + val h2 = g2.tupled.compose(f2.tupled) + println(h2(1, 2)) + + val h3 = h1.compose(h2) + println(h3(1, 2)) + + val f25 = + (x0: Int, x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int) => + (2 * x0, 2 * x1, 2 * x2, 2 * x3, 2 * x4, 2 * x5, 2 * x6, 2 * x7, 2 * x8, 2 * x9, 2 * x10, 2 * x11, 2 * x12, 2 * x13, 2 * x14, 2 * x15, 2 * x16, 2 * x17, 2 * x18, 2 * x19, 2 * x20, 2 * x21, 2 * x22, 2 * x23, 2 * x24) + val g25 = + (x0: Int, x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int) => + (3 * x0, 3 * x1, 3 * x2, 3 * x3, 3 * x4, 3 * x5, 3 * x6, 3 * x7, 3 * x8, 3 * x9, 3 * x10, 3 * x11, 3 * x12, 3 * x13, 3 * x14, 3 * x15, 3 * x16, 3 * x17, 3 * x18, 3 * x19, 3 * x20, 3 * x21, 3 * x22, 3 * x23, 3 * x24) + val h25 = f25.tupled.compose(g25.tupled) + println(h25(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)) + + } +} diff --git a/tests/run/tupled-function-extension-method.check b/tests/run/tupled-function-extension-method.check new file mode 100644 index 000000000000..efecf52bf9d9 --- /dev/null +++ b/tests/run/tupled-function-extension-method.check @@ -0,0 +1,5 @@ +() +(1) +(1,3) +(1,3,6) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25) diff --git a/tests/run/tupled-function-extension-method.scala b/tests/run/tupled-function-extension-method.scala new file mode 100644 index 000000000000..4db586c35680 --- /dev/null +++ b/tests/run/tupled-function-extension-method.scala @@ -0,0 +1,32 @@ +object Test { + def main(args: Array[String]): Unit = { + + val f0 = new Expr(() => ()) + val f1 = new Expr((i: Int) => Tuple1(i)) + val f2 = new Expr((i: Int, j: Int) => (i, i + j)) + val f3 = new Expr((i: Int, j: Int, k: Int) => (i, i + j, i + j + k)) + val f25 = new Expr( + (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int, x25: Int) => + (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25) + ) + + println(f0()) + println(f1(1)) + println(f2(1, 2)) + println(f3(1, 2, 3)) + println(f25(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)) + + } + + class Expr[T](val x: T) + + // Specialized only for arity 0 and one as auto tupling will not provide the disired effect + def (e: Expr[() => R]) apply[R](): R = e.x() + def (e: Expr[Arg => R]) apply[Arg, R](arg: Arg): R = e.x(arg) + + // Applied to all funtions of arity 2 or more (including more than 22 parameters) + def (e: Expr[F]) apply[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, Args, R]): R = { + tf.applyFunctionTo(e.x, args) + } + +} \ No newline at end of file diff --git a/tests/run/tupled-function-tupled.check b/tests/run/tupled-function-tupled.check new file mode 100644 index 000000000000..b4a487314d9c --- /dev/null +++ b/tests/run/tupled-function-tupled.check @@ -0,0 +1,3 @@ +276 +300 +325 diff --git a/tests/run/tupled-function-tupled.scala b/tests/run/tupled-function-tupled.scala new file mode 100644 index 000000000000..a69fd70feeab --- /dev/null +++ b/tests/run/tupled-function-tupled.scala @@ -0,0 +1,17 @@ +object Test { + def main(args: Array[String]): Unit = { + + val f23 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23 + val t23 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23) + println(f23.tupled(t23)) + + val f24 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23 + x24 + val t24 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) + println(f24.tupled(t24)) + + val f25 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int, x25: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 + val t25 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) + println(f25.tupled(t25)) + + } +} \ No newline at end of file diff --git a/tests/run/tupled-function.check b/tests/run/tupled-function.check new file mode 100644 index 000000000000..f56944496b49 --- /dev/null +++ b/tests/run/tupled-function.check @@ -0,0 +1,26 @@ +0 +1 +3 +6 +10 +15 +21 +28 +36 +45 +55 +66 +78 +91 +105 +120 +136 +153 +171 +190 +210 +231 +253 +276 +300 +325 diff --git a/tests/run/tupled-function.scala b/tests/run/tupled-function.scala new file mode 100644 index 000000000000..f42634596546 --- /dev/null +++ b/tests/run/tupled-function.scala @@ -0,0 +1,110 @@ +object Test { + def main(args: Array[String]): Unit = { + import TupledFunction._ + + val f0 = () => 0 + val t0 = () + println(f0(t0)) + + val f1 = (x: Int) => x + val t1 = Tuple1(1) + println(f1(t1)) + + val f2 = (x1: Int, x2: Int) => x1 + x2 + val t2 = (1, 2) + println(f2(t2)) + + val f3 = (x1: Int, x2: Int, x3: Int) => x1 + x2 + x3 + val t3 = (1, 2, 3) + println(f3(t3)) + + val f4 = (x1: Int, x2: Int, x3: Int, x4: Int) => x1 + x2 + x3 + x4 + val t4 = (1, 2, 3, 4) + println(f4(t4)) + + val f5 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int) => x1 + x2 + x3 + x4 + x5 + val t5 = (1, 2, 3, 4, 5) + println(f5(t5)) + + val f6 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int) => x1 + x2 + x3 + x4 + x5 + x6 + val t6 = (1, 2, 3, 4, 5, 6) + println(f6(t6)) + + val f7 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + val t7 = (1, 2, 3, 4, 5, 6, 7) + println(f7(t7)) + + val f8 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + val t8 = (1, 2, 3, 4, 5, 6, 7, 8) + println(f8(t8)) + + val f9 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + val t9 = (1, 2, 3, 4, 5, 6, 7, 8, 9) + println(f9(t9)) + + val f10 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + val t10 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + println(f10(t10)) + + val f11 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + val t11 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + println(f11(t11)) + + val f12 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + val t12 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) + println(f12(t12)) + + val f13 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + val t13 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) + println(f13(t13)) + + val f14 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + val t14 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) + println(f14(t14)) + + val f15 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + val t15 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) + println(f15(t15)) + + val f16 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + val t16 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) + println(f16(t16)) + + val f17 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + val t17 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) + println(f17(t17)) + + val f18 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + val t18 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) + println(f18(t18)) + + val f19 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + val t19 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) + println(f19(t19)) + + val f20 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + val t20 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) + println(f20(t20)) + + val f21 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + val t21 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) + println(f21(t21)) + + val f22 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + val t22 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) + println(f22(t22)) + + val f23 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23 + val t23 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23) + println(f23(t23)) + + val f24 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23 + x24 + val t24 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) + println(f24(t24)) + + val f25 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int, x25: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 + val t25 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) + println(f25(t25)) + + } +} \ No newline at end of file From 9a92ec7f7022024483a84c2da60d3bb71b2810fd Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 27 May 2019 10:41:32 +0200 Subject: [PATCH 02/14] Add auto funtion tupled `andThen` and `compose` --- library/src-3.x/scala/TupledFunction.scala | 10 ++++++++++ tests/run/tupled-function-andThen.scala | 8 ++++---- tests/run/tupled-function-compose.scala | 5 +++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/library/src-3.x/scala/TupledFunction.scala b/library/src-3.x/scala/TupledFunction.scala index 71c3a3796892..7b056731104a 100644 --- a/library/src-3.x/scala/TupledFunction.scala +++ b/library/src-3.x/scala/TupledFunction.scala @@ -13,4 +13,14 @@ object TupledFunction { def (f: F) apply[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, Args, R]): R = tf.applyFunctionTo(f, args) + /** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied last */ + def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given TupledFunction[G, GArgs, FArgs], TupledFunction[F, FArgs, R]: GArgs => R = { + x => f(g(x)) + } + + /** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied first */ + def (f: F) andThen[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given TupledFunction[F, FArgs, GArgs], TupledFunction[G, GArgs, R]: FArgs => R = { + x => g(f(x)) + } + } diff --git a/tests/run/tupled-function-andThen.scala b/tests/run/tupled-function-andThen.scala index 72c3cf62fdb0..b0d77fd95b64 100644 --- a/tests/run/tupled-function-andThen.scala +++ b/tests/run/tupled-function-andThen.scala @@ -1,14 +1,15 @@ object Test { def main(args: Array[String]): Unit = { + import TupledFunction._ val f1 = (x1: Int, x2: Int) => (x1, x2, x1 + x2) val g1 = (x1: Int, x2: Int, x3: Int) => x1 + x2 + x3 - val h1 = f1.tupled.andThen(g1.tupled) + val h1 = f1.andThen(g1) println(h1(1, 2)) val f2 = (x1: Int, x2: Int) => (1, x1, x2, x1 + x2, x1 * x2) val g2 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int) => (x1 + x2, x3 + x4 + x5) - val h2 = f2.tupled.andThen(g2.tupled) + val h2 = f2.andThen(g2) println(h2(1, 2)) val h3 = h2.andThen(h1) @@ -20,8 +21,7 @@ object Test { val g25 = (x0: Int, x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int) => (3 * x0, 3 * x1, 3 * x2, 3 * x3, 3 * x4, 3 * x5, 3 * x6, 3 * x7, 3 * x8, 3 * x9, 3 * x10, 3 * x11, 3 * x12, 3 * x13, 3 * x14, 3 * x15, 3 * x16, 3 * x17, 3 * x18, 3 * x19, 3 * x20, 3 * x21, 3 * x22, 3 * x23, 3 * x24) - val h25 = f25.tupled.andThen(g25.tupled) + val h25 = f25.andThen(g25) println(h25(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)) - } } diff --git a/tests/run/tupled-function-compose.scala b/tests/run/tupled-function-compose.scala index 6c22b3ba8327..90c76d5de1d5 100644 --- a/tests/run/tupled-function-compose.scala +++ b/tests/run/tupled-function-compose.scala @@ -1,14 +1,15 @@ object Test { def main(args: Array[String]): Unit = { + import TupledFunction._ val f1 = (x1: Int, x2: Int) => (x1, x2, x1 + x2) val g1 = (x1: Int, x2: Int, x3: Int) => x1 + x2 + x3 - val h1 = g1.tupled.compose(f1.tupled) + val h1 = g1.compose(f1) println(h1(1, 2)) val f2 = (x1: Int, x2: Int) => (1, x1, x2, x1 + x2, x1 * x2) val g2 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int) => (x1 + x2, x3 + x4 + x5) - val h2 = g2.tupled.compose(f2.tupled) + val h2 = g2.compose(f2) println(h2(1, 2)) val h3 = h1.compose(h2) From 24a1d00e0dc0aad01711119ac5b46cf9a85b8a66 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 27 May 2019 10:59:09 +0200 Subject: [PATCH 03/14] Add documentation --- library/src-3.x/dotty/DottyPredef.scala | 8 +++- library/src-3.x/scala/TupledFunction.scala | 47 ++++++++++++++++++++-- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/library/src-3.x/dotty/DottyPredef.scala b/library/src-3.x/dotty/DottyPredef.scala index 6fc437404fc3..c06054c6de57 100644 --- a/library/src-3.x/dotty/DottyPredef.scala +++ b/library/src-3.x/dotty/DottyPredef.scala @@ -39,8 +39,12 @@ object DottyPredef { inline def the[T] given (x: T): x.type = x /** Creates a tupled version of this function: instead of N arguments, - * it accepts a single [[scala.Tuple]] argument. - */ + * it accepts a single [[scala.Tuple]] argument. + * + * @tparam F the function type + * @tparam Args the tuple type with the same types as the function arguments of F + * @tparam R the return type of F + */ def (f: F) tupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args, R]): Args => R = { x => tf.applyFunctionTo(f, x) } diff --git a/library/src-3.x/scala/TupledFunction.scala b/library/src-3.x/scala/TupledFunction.scala index 7b056731104a..a47c940b7102 100644 --- a/library/src-3.x/scala/TupledFunction.scala +++ b/library/src-3.x/scala/TupledFunction.scala @@ -2,23 +2,64 @@ package scala import scala.annotation.implicitNotFound +/** Type class relating a `FunctionN[..., R]` with an equvalent tupled function `Function1[TupleN[...], R]` + * + * @tparam F a function type + * @tparam Args a tuple type with the same types as the function arguments of F + * @tparam R the return type of F + */ @implicitNotFound("${F} cannot be tupled as ${Args} => ${R}") trait TupledFunction[F, Args <: Tuple, R] { def applyFunctionTo(f: F, args: Args): R } +/** Module of TupledFunction containing methods for auto function tupling + * + * Usage + * ``` + * val t2: (Int, Int) = ??? + * val t3: (Int, Int, Int) = ??? + * val f1: (Int, Int) => (Int, Int, Int) = ??? + * val f2: (Int, Int, Int) => (Int, Int) = ??? + * + * import TupledFunction._ + * f1(t2) + * f2(t3) + * val f3: (Int, Int) => (Int, Int) = f1.andThen(f2) + * val f4: (Int, Int, Int) => (Int, Int, Int) = f1.compose(f2) + * ``` + */ object TupledFunction { - /** Apply this function to with each element of the tuple as a parameter */ + /** Apply this function to with each element of the tuple as a parameter + * + * @tparam F the function type + * @tparam Args the tuple type with the same types as the function arguments of F + * @tparam R the return type of F + */ def (f: F) apply[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, Args, R]): R = tf.applyFunctionTo(f, args) - /** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied last */ + /** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied last + * + * @tparam F a function type + * @tparam G a function type + * @tparam FArgs the tuple type with the same types as the function arguments of F and return type of G + * @tparam GArgs the tuple type with the same types as the function arguments of G + * @tparam R the return type of F + */ def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given TupledFunction[G, GArgs, FArgs], TupledFunction[F, FArgs, R]: GArgs => R = { x => f(g(x)) } - /** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied first */ + /** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied first + * + * @tparam F a function type + * @tparam G a function type + * @tparam FArgs the tuple type with the same types as the function arguments of F + * @tparam GArgs the tuple type with the same types as the function arguments of G and return type of F + * @tparam R the return type of G + */ def (f: F) andThen[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given TupledFunction[F, FArgs, GArgs], TupledFunction[G, GArgs, R]: FArgs => R = { x => g(f(x)) } From c9e5c2bc079d1fb5aa6965e7b44793ea6e0ab70b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 27 May 2019 16:04:19 +0200 Subject: [PATCH 04/14] Fix typo --- compiler/src/dotty/tools/dotc/core/Definitions.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Implicits.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index a70c58dacbcf..51d64b248bb9 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -796,7 +796,7 @@ class Definitions { TupleXXLModule.info.member(nme.apply).requiredSymbol("method", nme.apply, TupleXXLModule)(_.info.isVarArgsMethod) lazy val TupledFunctionTypeRef: TypeRef = ctx.requiredClassRef("scala.TupledFunction") - def TupleFunctionClass(implicit ctx: Context): ClassSymbol = TupledFunctionTypeRef.symbol.asClass + def TupledFunctionClass(implicit ctx: Context): ClassSymbol = TupledFunctionTypeRef.symbol.asClass lazy val InternalTupledFunctionTypeRef: TypeRef = ctx.requiredClassRef("scala.internal.TupledFunction") def InternalTupleFunctionClass(implicit ctx: Context): ClassSymbol = InternalTupledFunctionTypeRef.symbol.asClass diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index bac22aa99341..8f7cb43e8e78 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -848,7 +848,7 @@ trait Implicits { self: Typer => trySpecialCase(defn.GenericClass, synthesizedGeneric, trySpecialCase(defn.TastyReflectionClass, synthesizedTastyContext, trySpecialCase(defn.EqlClass, synthesizedEq, - trySpecialCase(defn.TupleFunctionClass, synthesizedTupleFunction, + trySpecialCase(defn.TupledFunctionClass, synthesizedTupleFunction, trySpecialCase(defn.ValueOfClass, synthesizedValueOf, failed))))))) } } From 33d7e96edb996eb0eb6157d40a7591c468d9675b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 28 May 2019 09:19:44 +0200 Subject: [PATCH 05/14] Use TupledFunction[F, G] as function tupling instead of application Also added support for tupled implicit functions ``` TupledFunction[given (Int, Int) => Int, given ((Int, Int)) => Int] ``` --- .../dotty/tools/dotc/typer/Implicits.scala | 18 ++- library/src-3.x/dotty/DottyPredef.scala | 4 +- library/src-3.x/scala/TupledFunction.scala | 17 +-- .../scala/internal/TupledFunction.scala | 117 +++++++-------- tests/neg/tupled-function-instances.scala | 142 +++++++++--------- tests/pos/tupled-function-instances.scala | 88 +++++++---- .../tupled-function-extension-method.check | 4 + .../tupled-function-extension-method.scala | 21 ++- 8 files changed, 222 insertions(+), 189 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 8f7cb43e8e78..430658acae72 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -711,18 +711,22 @@ trait Implicits { self: Typer => def synthesizedTupleFunction(formal: Type): Tree = { formal match { - case AppliedType(_, fun :: args :: ret :: Nil) if defn.isFunctionType(fun) => - val funTypes = fun.dropDependentRefinement.dealias.argInfos - if (defn.tupleType(funTypes.init) =:= args && funTypes.last =:= ret) { + case AppliedType(_, funArgs @ fun :: tupled :: Nil) if defn.isFunctionType(fun) && defn.isFunctionType(tupled) => + lazy val funTypes = fun.dropDependentRefinement.dealias.argInfos + lazy val tupledTypes = tupled.dropDependentRefinement.dealias.argInfos + if ( + defn.isImplicitFunctionType(fun) == defn.isImplicitFunctionType(tupled) && + tupledTypes.size == 2 && + defn.tupleType(funTypes.init) =:= tupledTypes.head && + funTypes.last =:= tupledTypes.last + ) { val arity = funTypes.size - 1 if (defn.isErasedFunctionType(fun)) EmptyTree // TODO support? - else if (defn.isImplicitFunctionType(fun)) - EmptyTree // TODO support else if (arity <= Definitions.MaxImplementedFunctionArity) - ref(defn.InternalTupleFunctionModule).select(s"tupledFunction$arity".toTermName).appliedToTypes(funTypes) + ref(defn.InternalTupleFunctionModule).select(s"tupledFunction$arity".toTermName).appliedToTypes(funArgs) else - ref(defn.InternalTupleFunctionModule).select("tupledFunctionXXL".toTermName).appliedToTypes(fun :: args :: ret :: Nil) + ref(defn.InternalTupleFunctionModule).select("tupledFunctionXXL".toTermName).appliedToTypes(funArgs) } else EmptyTree case _ => EmptyTree diff --git a/library/src-3.x/dotty/DottyPredef.scala b/library/src-3.x/dotty/DottyPredef.scala index c06054c6de57..fb490fee51d7 100644 --- a/library/src-3.x/dotty/DottyPredef.scala +++ b/library/src-3.x/dotty/DottyPredef.scala @@ -45,8 +45,6 @@ object DottyPredef { * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F */ - def (f: F) tupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args, R]): Args => R = { - x => tf.applyFunctionTo(f, x) - } + def (f: F) tupled[F, Args <: Tuple, R] given (tupled: TupledFunction[F, Args => R]): Args => R = tupled(f) } diff --git a/library/src-3.x/scala/TupledFunction.scala b/library/src-3.x/scala/TupledFunction.scala index a47c940b7102..90a49b047d3f 100644 --- a/library/src-3.x/scala/TupledFunction.scala +++ b/library/src-3.x/scala/TupledFunction.scala @@ -5,12 +5,11 @@ import scala.annotation.implicitNotFound /** Type class relating a `FunctionN[..., R]` with an equvalent tupled function `Function1[TupleN[...], R]` * * @tparam F a function type - * @tparam Args a tuple type with the same types as the function arguments of F - * @tparam R the return type of F + * @tparam G a tupled function type (function of arity 1 receiving a tuple as argument) */ -@implicitNotFound("${F} cannot be tupled as ${Args} => ${R}") -trait TupledFunction[F, Args <: Tuple, R] { - def applyFunctionTo(f: F, args: Args): R +@implicitNotFound("${F} cannot be tupled as ${G}") +trait TupledFunction[F, G] { + def apply(f: F): G } /** Module of TupledFunction containing methods for auto function tupling @@ -37,8 +36,8 @@ object TupledFunction { * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F */ - def (f: F) apply[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, Args, R]): R = - tf.applyFunctionTo(f, args) + def (f: F) apply[F, Args <: Tuple, R](args: Args) given (tupled: TupledFunction[F, Args => R]): R = + tupled(f)(args) /** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied last * @@ -48,7 +47,7 @@ object TupledFunction { * @tparam GArgs the tuple type with the same types as the function arguments of G * @tparam R the return type of F */ - def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given TupledFunction[G, GArgs, FArgs], TupledFunction[F, FArgs, R]: GArgs => R = { + def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given TupledFunction[G, GArgs => FArgs], TupledFunction[F, FArgs => R]: GArgs => R = { x => f(g(x)) } @@ -60,7 +59,7 @@ object TupledFunction { * @tparam GArgs the tuple type with the same types as the function arguments of G and return type of F * @tparam R the return type of G */ - def (f: F) andThen[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given TupledFunction[F, FArgs, GArgs], TupledFunction[G, GArgs, R]: FArgs => R = { + def (f: F) andThen[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given TupledFunction[F, FArgs => GArgs], TupledFunction[G, GArgs => R]: FArgs => R = { x => g(f(x)) } diff --git a/library/src-3.x/scala/internal/TupledFunction.scala b/library/src-3.x/scala/internal/TupledFunction.scala index 11b3eddfd7ef..2c787fbb92d5 100644 --- a/library/src-3.x/scala/internal/TupledFunction.scala +++ b/library/src-3.x/scala/internal/TupledFunction.scala @@ -2,118 +2,103 @@ package scala.internal object TupledFunction { - def tupledFunction0[R]: TupledFunction[() => R, Unit, R] = new TupledFunction { - def applyFunctionTo(f: () => R, args: Unit): R = f() + def tupledFunction0[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = + ((args: Unit) => f.asInstanceOf[() => Any].apply()).asInstanceOf[G] } - def tupledFunction1[T1, R]: TupledFunction[T1 => R, Tuple1[T1], R] = new TupledFunction { - def applyFunctionTo(f: T1 => R, args: Tuple1[T1]): R = f(args._1) + def tupledFunction1[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = + ((args: Tuple1[Any]) => f.asInstanceOf[Any => Any].apply(args._1)).asInstanceOf[G] } - def tupledFunction2[T1, T2, R]: TupledFunction[(T1, T2) => R, Tuple2[T1, T2], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2) => R, args: Tuple2[T1, T2]): R = f(args._1, args._2) + def tupledFunction2[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function2[_, _, _]].tupled.asInstanceOf[G] } - def tupledFunction3[T1, T2, T3, R]: TupledFunction[(T1, T2, T3) => R, Tuple3[T1, T2, T3], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3) => R, args: Tuple3[T1, T2, T3]): R = f(args._1, args._2, args._3) + def tupledFunction3[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function3[_, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction4[T1, T2, T3, T4, R]: TupledFunction[(T1, T2, T3, T4) => R, Tuple4[T1, T2, T3, T4], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4) => R, args: Tuple4[T1, T2, T3, T4]): R = f(args._1, args._2, args._3, args._4) + def tupledFunction4[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function4[_, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction5[T1, T2, T3, T4, T5, R]: TupledFunction[(T1, T2, T3, T4, T5) => R, Tuple5[T1, T2, T3, T4, T5], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5) => R, args: Tuple5[T1, T2, T3, T4, T5]): R = f(args._1, args._2, args._3, args._4, args._5) + def tupledFunction5[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function5[_, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction6[T1, T2, T3, T4, T5, T6, R]: TupledFunction[(T1, T2, T3, T4, T5, T6) => R, Tuple6[T1, T2, T3, T4, T5, T6], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6) => R, args: Tuple6[T1, T2, T3, T4, T5, T6]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6) + def tupledFunction6[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function6[_, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction7[T1, T2, T3, T4, T5, T6, T7, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7) => R, Tuple7[T1, T2, T3, T4, T5, T6, T7], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7) => R, args: Tuple7[T1, T2, T3, T4, T5, T6, T7]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7) + def tupledFunction7[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function7[_, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8) => R, Tuple8[T1, T2, T3, T4, T5, T6, T7, T8], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8) => R, args: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8) + def tupledFunction8[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function8[_, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9) => R, Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9) => R, args: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9) + def tupledFunction9[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function9[_, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => R, Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => R, args: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10) + def tupledFunction10[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function10[_, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) => R, Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) => R, args: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11) + def tupledFunction11[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function11[_, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) => R, Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) => R, args: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12) + def tupledFunction12[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function12[_, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) => R, Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) => R, args: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13) + def tupledFunction13[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function13[_, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) => R, Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) => R, args: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14) + def tupledFunction14[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) => R, Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) => R, args: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15) + def tupledFunction15[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) => R, Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) => R, args: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16) + def tupledFunction16[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) => R, Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) => R, args: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17) + def tupledFunction17[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) => R, Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) => R, args: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17, args._18) + def tupledFunction18[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) => R, Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) => R, args: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17, args._18, args._19) + def tupledFunction19[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) => R, Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) => R, args: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17, args._18, args._19, args._20) + def tupledFunction20[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) => R, Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) => R, args: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17, args._18, args._19, args._20, args._21) + def tupledFunction21[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]: TupledFunction[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) => R, Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22], R] = new TupledFunction { - def applyFunctionTo(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) => R, args: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]): R = - f(args._1, args._2, args._3, args._4, args._5, args._6, args._7, args._8, args._9, args._10, args._11, args._12, args._13, args._14, args._15, args._16, args._17, args._18, args._19, args._20, args._21, args._22) + def tupledFunction22[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } - def tupledFunctionXXL[F, Args <: Tuple, R]: TupledFunction[F, Args, R] = new TupledFunction { - def applyFunctionTo(f: F, args: Args): R = - f.asInstanceOf[FunctionXXL].apply(args.asInstanceOf[TupleXXL].elems).asInstanceOf[R] + def tupledFunctionXXL[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = + ((args: TupleXXL) => f.asInstanceOf[FunctionXXL].apply(args.elems)).asInstanceOf[G] } } diff --git a/tests/neg/tupled-function-instances.scala b/tests/neg/tupled-function-instances.scala index ab120ca95d9f..75f3c7b27869 100644 --- a/tests/neg/tupled-function-instances.scala +++ b/tests/neg/tupled-function-instances.scala @@ -1,82 +1,74 @@ object Test { def main(args: Array[String]): Unit = { + type T type R - the[TupledFunction[given 1 => R, Tuple1[1], R]] // error - the[TupledFunction[given (1, 2) => R, (1, 2), R]] // error - the[TupledFunction[given (1, 2, 3) => R, (1, 2, 3), R]] // error - the[TupledFunction[given (1, 2, 3, 4) => R, (1, 2, 3, 4), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5) => R, (1, 2, 3, 4, 5), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6) => R, (1, 2, 3, 4, 5, 6), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7) => R, (1, 2, 3, 4, 5, 6, 7), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8) => R, (1, 2, 3, 4, 5, 6, 7, 8), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), R]] // error - the[TupledFunction[given (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), R]] // error - the[TupledFunction[erased 1 => R, Tuple1[1], R]] // error - the[TupledFunction[erased (1, 2) => R, (1, 2), R]] // error - the[TupledFunction[erased (1, 2, 3) => R, (1, 2, 3), R]] // error - the[TupledFunction[erased (1, 2, 3, 4) => R, (1, 2, 3, 4), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5) => R, (1, 2, 3, 4, 5), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6) => R, (1, 2, 3, 4, 5, 6), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7) => R, (1, 2, 3, 4, 5, 6, 7), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8) => R, (1, 2, 3, 4, 5, 6, 7, 8), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), R]] // error - the[TupledFunction[erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), R]] // error + the[TupledFunction[Nothing, ((T, T, T)) => R]] // error + the[TupledFunction[Any, ((T, T, T)) => R]] // error + the[TupledFunction[Tuple1[Int], ((T, T, T)) => R]] // error - the[TupledFunction[given erased 1 => R, Tuple1[1], R]] // error - the[TupledFunction[given erased (1, 2) => R, (1, 2), R]] // error - the[TupledFunction[given erased (1, 2, 3) => R, (1, 2, 3), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4) => R, (1, 2, 3, 4), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5) => R, (1, 2, 3, 4, 5), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6) => R, (1, 2, 3, 4, 5, 6), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7) => R, (1, 2, 3, 4, 5, 6, 7), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8) => R, (1, 2, 3, 4, 5, 6, 7, 8), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), R]] // error - the[TupledFunction[given erased (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), R]] // error + the[TupledFunction[(T, T, T))=> R, Nothing]] // error + the[TupledFunction[(T, T, T) => R, Any]] // error + the[TupledFunction[((T, T, T)) => R, Tuple1[Int]]] // error + + the[TupledFunction[() => R, () => R]] // error + the[TupledFunction[() => Unit, () => Unit]] // error + the[TupledFunction[(T, T, T) => R, () => R]] // error + the[TupledFunction[(T, T, T) => R, (T, T) => R]] // error + + the[TupledFunction[(T, T, T) => R, given ((T, T, T)) => R]] // error + the[TupledFunction[given (T, T, T) => R, ((T, T, T)) => R]] // error + + the[TupledFunction[erased T => R, erased Tuple1[T] => R]] // error + the[TupledFunction[erased (T, T) => R, erased ((T, T)) => R]] // error + the[TupledFunction[erased (T, T, T) => R, erased ((T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T) => R, erased ((T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T) => R, erased ((T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + + the[TupledFunction[given erased T => R, given erased Tuple1[T] => R]] // error + the[TupledFunction[given erased (T, T) => R, given erased ((T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T) => R, given erased ((T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T) => R, given erased ((T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T) => R, given erased ((T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error + the[TupledFunction[given erased (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given erased ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] // error } } \ No newline at end of file diff --git a/tests/pos/tupled-function-instances.scala b/tests/pos/tupled-function-instances.scala index 8301788e97d8..20fbe4c00356 100644 --- a/tests/pos/tupled-function-instances.scala +++ b/tests/pos/tupled-function-instances.scala @@ -1,31 +1,67 @@ object Test { def main(args: Array[String]): Unit = { + type T type R - the[TupledFunction[() => R, Unit, R]] - the[TupledFunction[1 => R, Tuple1[1], R]] - the[TupledFunction[(1, 2) => R, (1, 2), R]] - the[TupledFunction[(1, 2, 3) => R, (1, 2, 3), R]] - the[TupledFunction[(1, 2, 3, 4) => R, (1, 2, 3, 4), R]] - the[TupledFunction[(1, 2, 3, 4, 5) => R, (1, 2, 3, 4, 5), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6) => R, (1, 2, 3, 4, 5, 6), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7) => R, (1, 2, 3, 4, 5, 6, 7), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8) => R, (1, 2, 3, 4, 5, 6, 7, 8), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), R]] - the[TupledFunction[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) => R, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), R]] + + the[TupledFunction[() => R, Unit => R]] + the[TupledFunction[T => R, Tuple1[T] => R]] + the[TupledFunction[(T, T) => R, ((T, T)) => R]] + the[TupledFunction[(T, T, T) => R, ((T, T, T)) => R]] + the[TupledFunction[(T, T, T, T) => R, ((T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T) => R, ((T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T) => R, ((T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + + the[TupledFunction[given T => R, given Tuple1[T] => R]] + the[TupledFunction[given (T, T) => R, given ((T, T)) => R]] + the[TupledFunction[given (T, T, T) => R, given ((T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T) => R, given ((T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T) => R, given ((T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T) => R, given ((T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + the[TupledFunction[given (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => R, given ((T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) => R]] + + + type F2 = (T, T) => R + type TF2 = ((T, T)) => R + the[TupledFunction[F2, ((T, T)) => R]] + the[TupledFunction[(T, T) => R, TF2]] + the[TupledFunction[F2, TF2]] + } } \ No newline at end of file diff --git a/tests/run/tupled-function-extension-method.check b/tests/run/tupled-function-extension-method.check index efecf52bf9d9..6f8d92537745 100644 --- a/tests/run/tupled-function-extension-method.check +++ b/tests/run/tupled-function-extension-method.check @@ -3,3 +3,7 @@ (1,3) (1,3,6) (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25) +(1) +(1,3) +(1,3,6) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25) diff --git a/tests/run/tupled-function-extension-method.scala b/tests/run/tupled-function-extension-method.scala index 4db586c35680..b459f78f5361 100644 --- a/tests/run/tupled-function-extension-method.scala +++ b/tests/run/tupled-function-extension-method.scala @@ -16,6 +16,19 @@ object Test { println(f3(1, 2, 3)) println(f25(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)) + val if1 = new Expr(given (i: Int) => Tuple1(i)) + val if2 = new Expr(given (i: Int, j: Int) => (i, i + j)) + val if3 = new Expr(given (i: Int, j: Int, k: Int) => (i, i + j, i + j + k)) + val if25 = new Expr( + given (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int, x25: Int) => + (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25) + ) + + println(if1.applyGiven(1)) + println(if2.applyGiven(1, 2)) + println(if3.applyGiven(1, 2, 3)) + println(if25.applyGiven(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)) + } class Expr[T](val x: T) @@ -23,10 +36,12 @@ object Test { // Specialized only for arity 0 and one as auto tupling will not provide the disired effect def (e: Expr[() => R]) apply[R](): R = e.x() def (e: Expr[Arg => R]) apply[Arg, R](arg: Arg): R = e.x(arg) + def (e: Expr[given Arg => R]) applyGiven[Arg, R](arg: Arg): R = e.x given arg // Applied to all funtions of arity 2 or more (including more than 22 parameters) - def (e: Expr[F]) apply[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, Args, R]): R = { - tf.applyFunctionTo(e.x, args) - } + def (e: Expr[F]) apply[F, Args <: Tuple, R](args: Args) given (tupled: TupledFunction[F, Args => R]): R = + tupled(e.x)(args) + def (e: Expr[F]) applyGiven[F, Args <: Tuple, R](args: Args) given (tupled: TupledFunction[F, given Args => R]): R = + tupled(e.x) given args } \ No newline at end of file From 5f07a1750b188740597caa03a5118918964c6a6d Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 28 May 2019 09:50:36 +0200 Subject: [PATCH 06/14] Add documentation --- library/src-3.x/dotty/DottyPredef.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/src-3.x/dotty/DottyPredef.scala b/library/src-3.x/dotty/DottyPredef.scala index fb490fee51d7..4936faef36ea 100644 --- a/library/src-3.x/dotty/DottyPredef.scala +++ b/library/src-3.x/dotty/DottyPredef.scala @@ -41,6 +41,8 @@ object DottyPredef { /** Creates a tupled version of this function: instead of N arguments, * it accepts a single [[scala.Tuple]] argument. * + * This is a generalization of [[scala.FunctionN.tupled]] that work on functions of any arity + * * @tparam F the function type * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F From f6eb444938962f72826752d13fbff6a21f63604f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 28 May 2019 09:57:49 +0200 Subject: [PATCH 07/14] Remove TupledFunction tuppled, apply, andThen and compose from stdlib All these operations can and probably should be implemented in a library. --- library/src-3.x/dotty/DottyPredef.scala | 11 ---- library/src-3.x/scala/TupledFunction.scala | 53 ------------------- tests/run/tupled-function-andThen.scala | 14 ++++- ...tion.check => tupled-function-apply.check} | 0 ...tion.scala => tupled-function-apply.scala} | 10 +++- tests/run/tupled-function-compose.scala | 16 +++++- tests/run/tupled-function-tupled.scala | 11 ++++ 7 files changed, 47 insertions(+), 68 deletions(-) rename tests/run/{tupled-function.check => tupled-function-apply.check} (100%) rename tests/run/{tupled-function.scala => tupled-function-apply.scala} (95%) diff --git a/library/src-3.x/dotty/DottyPredef.scala b/library/src-3.x/dotty/DottyPredef.scala index 4936faef36ea..cdfa72ec1882 100644 --- a/library/src-3.x/dotty/DottyPredef.scala +++ b/library/src-3.x/dotty/DottyPredef.scala @@ -38,15 +38,4 @@ object DottyPredef { inline def the[T] given (x: T): x.type = x - /** Creates a tupled version of this function: instead of N arguments, - * it accepts a single [[scala.Tuple]] argument. - * - * This is a generalization of [[scala.FunctionN.tupled]] that work on functions of any arity - * - * @tparam F the function type - * @tparam Args the tuple type with the same types as the function arguments of F - * @tparam R the return type of F - */ - def (f: F) tupled[F, Args <: Tuple, R] given (tupled: TupledFunction[F, Args => R]): Args => R = tupled(f) - } diff --git a/library/src-3.x/scala/TupledFunction.scala b/library/src-3.x/scala/TupledFunction.scala index 90a49b047d3f..577c089f11bc 100644 --- a/library/src-3.x/scala/TupledFunction.scala +++ b/library/src-3.x/scala/TupledFunction.scala @@ -11,56 +11,3 @@ import scala.annotation.implicitNotFound trait TupledFunction[F, G] { def apply(f: F): G } - -/** Module of TupledFunction containing methods for auto function tupling - * - * Usage - * ``` - * val t2: (Int, Int) = ??? - * val t3: (Int, Int, Int) = ??? - * val f1: (Int, Int) => (Int, Int, Int) = ??? - * val f2: (Int, Int, Int) => (Int, Int) = ??? - * - * import TupledFunction._ - * f1(t2) - * f2(t3) - * val f3: (Int, Int) => (Int, Int) = f1.andThen(f2) - * val f4: (Int, Int, Int) => (Int, Int, Int) = f1.compose(f2) - * ``` - */ -object TupledFunction { - - /** Apply this function to with each element of the tuple as a parameter - * - * @tparam F the function type - * @tparam Args the tuple type with the same types as the function arguments of F - * @tparam R the return type of F - */ - def (f: F) apply[F, Args <: Tuple, R](args: Args) given (tupled: TupledFunction[F, Args => R]): R = - tupled(f)(args) - - /** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied last - * - * @tparam F a function type - * @tparam G a function type - * @tparam FArgs the tuple type with the same types as the function arguments of F and return type of G - * @tparam GArgs the tuple type with the same types as the function arguments of G - * @tparam R the return type of F - */ - def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given TupledFunction[G, GArgs => FArgs], TupledFunction[F, FArgs => R]: GArgs => R = { - x => f(g(x)) - } - - /** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied first - * - * @tparam F a function type - * @tparam G a function type - * @tparam FArgs the tuple type with the same types as the function arguments of F - * @tparam GArgs the tuple type with the same types as the function arguments of G and return type of F - * @tparam R the return type of G - */ - def (f: F) andThen[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given TupledFunction[F, FArgs => GArgs], TupledFunction[G, GArgs => R]: FArgs => R = { - x => g(f(x)) - } - -} diff --git a/tests/run/tupled-function-andThen.scala b/tests/run/tupled-function-andThen.scala index b0d77fd95b64..aef16590c844 100644 --- a/tests/run/tupled-function-andThen.scala +++ b/tests/run/tupled-function-andThen.scala @@ -1,6 +1,5 @@ object Test { def main(args: Array[String]): Unit = { - import TupledFunction._ val f1 = (x1: Int, x2: Int) => (x1, x2, x1 + x2) val g1 = (x1: Int, x2: Int, x3: Int) => x1 + x2 + x3 @@ -24,4 +23,17 @@ object Test { val h25 = f25.andThen(g25) println(h25(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)) } + + /** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied first + * + * @tparam F a function type + * @tparam G a function type + * @tparam FArgs the tuple type with the same types as the function arguments of F + * @tparam GArgs the tuple type with the same types as the function arguments of G and return type of F + * @tparam R the return type of G + */ + def (f: F) andThen[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given (tf: TupledFunction[F, FArgs => GArgs], tg: TupledFunction[G, GArgs => R]): FArgs => R = { + x => tg(g)(tf(f)(x)) + } + } diff --git a/tests/run/tupled-function.check b/tests/run/tupled-function-apply.check similarity index 100% rename from tests/run/tupled-function.check rename to tests/run/tupled-function-apply.check diff --git a/tests/run/tupled-function.scala b/tests/run/tupled-function-apply.scala similarity index 95% rename from tests/run/tupled-function.scala rename to tests/run/tupled-function-apply.scala index f42634596546..71af04efc293 100644 --- a/tests/run/tupled-function.scala +++ b/tests/run/tupled-function-apply.scala @@ -1,6 +1,5 @@ object Test { def main(args: Array[String]): Unit = { - import TupledFunction._ val f0 = () => 0 val t0 = () @@ -107,4 +106,13 @@ object Test { println(f25(t25)) } + + /** Apply this function to with each element of the tuple as a parameter + * + * @tparam F the function type + * @tparam Args the tuple type with the same types as the function arguments of F + * @tparam R the return type of F + */ + def (f: F) apply[F, Args <: Tuple, R](args: Args) given (tupled: TupledFunction[F, Args => R]): R = + tupled(f)(args) } \ No newline at end of file diff --git a/tests/run/tupled-function-compose.scala b/tests/run/tupled-function-compose.scala index 90c76d5de1d5..d4ff04512bad 100644 --- a/tests/run/tupled-function-compose.scala +++ b/tests/run/tupled-function-compose.scala @@ -1,6 +1,5 @@ object Test { def main(args: Array[String]): Unit = { - import TupledFunction._ val f1 = (x1: Int, x2: Int) => (x1, x2, x1 + x2) val g1 = (x1: Int, x2: Int, x3: Int) => x1 + x2 + x3 @@ -21,8 +20,21 @@ object Test { val g25 = (x0: Int, x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int) => (3 * x0, 3 * x1, 3 * x2, 3 * x3, 3 * x4, 3 * x5, 3 * x6, 3 * x7, 3 * x8, 3 * x9, 3 * x10, 3 * x11, 3 * x12, 3 * x13, 3 * x14, 3 * x15, 3 * x16, 3 * x17, 3 * x18, 3 * x19, 3 * x20, 3 * x21, 3 * x22, 3 * x23, 3 * x24) - val h25 = f25.tupled.compose(g25.tupled) + val h25 = f25.compose(g25) println(h25(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)) } + + /** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied last + * + * @tparam F a function type + * @tparam G a function type + * @tparam FArgs the tuple type with the same types as the function arguments of F and return type of G + * @tparam GArgs the tuple type with the same types as the function arguments of G + * @tparam R the return type of F + */ + def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given (tg: TupledFunction[G, GArgs => FArgs], tf: TupledFunction[F, FArgs => R]): GArgs => R = { + x => tf(f)(tg(g)(x)) + } + } diff --git a/tests/run/tupled-function-tupled.scala b/tests/run/tupled-function-tupled.scala index a69fd70feeab..e22cde095db9 100644 --- a/tests/run/tupled-function-tupled.scala +++ b/tests/run/tupled-function-tupled.scala @@ -14,4 +14,15 @@ object Test { println(f25.tupled(t25)) } + + /** Creates a tupled version of this function: instead of N arguments, + * it accepts a single [[scala.Tuple]] argument. + * + * This is a generalization of [[scala.FunctionN.tupled]] that work on functions of any arity + * + * @tparam F the function type + * @tparam Args the tuple type with the same types as the function arguments of F + * @tparam R the return type of F + */ + def (f: F) tupled[F, Args <: Tuple, R] given (tupled: TupledFunction[F, Args => R]): Args => R = tupled(f) } \ No newline at end of file From baec08b9c6f558f09ffa7e641f9317be8e41f441 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 28 May 2019 10:42:49 +0200 Subject: [PATCH 08/14] Add documentation --- .../other-new-features/tupled-function.md | 55 +++++++++++++++++++ docs/sidebar.yml | 2 + 2 files changed, 57 insertions(+) create mode 100644 docs/docs/reference/other-new-features/tupled-function.md diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md new file mode 100644 index 000000000000..bc5769782d29 --- /dev/null +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -0,0 +1,55 @@ +--- +layout: doc-page +title: "Tupled Function" +--- + +Tupled Function +---------------------- + +With functions bounded to arities up to 22 it was possible to generalize some operation on all function types using overloading. +Now that we have functions and tuples generalized to [arities above 22](https://dotty.epfl.ch/docs/reference/dropped-features/limit22.html) overloading is not an option anymore. +The type class `TupleFunction` provides a way to abstract directly over functions of any arity converting it to an equivalent function that receives all arguments in a single tuple. + +```scala +/** Type class relating a `FunctionN[..., R]` with an equvalent tupled function `Function1[TupleN[...], R]` + * + * @tparam F a function type + * @tparam G a tupled function type (function of arity 1 receiving a tuple as argument) + */ +@implicitNotFound("${F} cannot be tupled as ${G}") +trait TupledFunction[F, G] { + def apply(f: F): G +} +``` + + +Examples +-------- +`TupledFunction` can be used to generalize the `Tuple2.tupled`, ... `Tuple22.tupled` method to functions of any arities ([full example](https://github.com/lampepfl/dotty/tests/run/tupled-function-tupled.scala)) + +```scala +/** Creates a tupled version of this function: instead of N arguments, + * it accepts a single [[scala.Tuple]] argument. + * + * @tparam F the function type + * @tparam Args the tuple type with the same types as the function arguments of F + * @tparam R the return type of F + */ +def (f: F) tupled[F, Args <: Tuple, R] given (tupled: TupledFunction[F, Args => R]): Args => R = tupled(f) +``` + +`TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/lampepfl/dotty/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/lampepfl/dotty/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples. + +```scala +/** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied last + * + * @tparam F a function type + * @tparam G a function type + * @tparam FArgs the tuple type with the same types as the function arguments of F and return type of G + * @tparam GArgs the tuple type with the same types as the function arguments of G + * @tparam R the return type of F + */ +def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given (tupledG: TupledFunction[G, GArgs => FArgs], tupledF: TupledFunction[F, FArgs => R]): GArgs => R = { + (x: GArgs) => tupledF(f)(tupledG(g)(x)) +} +``` diff --git a/docs/sidebar.yml b/docs/sidebar.yml index a25063ae4746..97255e850254 100644 --- a/docs/sidebar.yml +++ b/docs/sidebar.yml @@ -89,6 +89,8 @@ sidebar: url: docs/reference/other-new-features/erased-terms.html - title: Kind Polymorphism url: docs/reference/other-new-features/kind-polymorphism.html + - title: Tupled Function + url: docs/reference/other-new-features/tupled-function.html - title: Other Changed Features subsection: - title: Volatile Lazy Vals From 22162bec7e2b0d255c5e8a36fd934652242f2935 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 28 May 2019 10:47:17 +0200 Subject: [PATCH 09/14] Improve documentation --- docs/docs/reference/dropped-features/limit22.md | 5 +++-- docs/docs/reference/other-new-features/tupled-function.md | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/docs/reference/dropped-features/limit22.md b/docs/docs/reference/dropped-features/limit22.md index 285dcb543629..ed1fe7e44435 100644 --- a/docs/docs/reference/dropped-features/limit22.md +++ b/docs/docs/reference/dropped-features/limit22.md @@ -7,7 +7,8 @@ The limits of 22 for the maximal number of parameters of function types and the maximal number of fields in tuple types have been dropped. Functions can now have an arbitrary number of -parameters. Functions beyond Function22 are represented with a new trait -`scala.FunctionXXL`. +parameters. Functions beyond Function22 are erased to a new trait +`scala.FunctionXXL` and tuples beyond Tuple22 are erased to a new trait `scala.TupleXXL`. +Both of these are implemented using arrays. Tuples can also have an arbitrary number of fields. Furthermore, they support generic operation such as concatenation and indexing. diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md index bc5769782d29..d5a2d2d79e4f 100644 --- a/docs/docs/reference/other-new-features/tupled-function.md +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -22,6 +22,12 @@ trait TupledFunction[F, G] { } ``` +The compiler will synthesize an instance of `TupledFunction[F, G]` if: + +* `F` is a function type of arity `N` +* `G` is a function with a single tuple argument of size `N` and it's types are equal to the arguments of `F` +* The return type of `F` is equal to the return type of `G` +* `F` and `G` are the same kind of functions (`given` arguments or not) Examples -------- From 3c2005d01e587cb782fea689b4e27b8bb0b6e958 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 28 May 2019 11:00:02 +0200 Subject: [PATCH 10/14] Seal TupledFunction to only have instances in internal --- .../other-new-features/tupled-function.md | 2 +- library/src-3.x/scala/TupledFunction.scala | 109 +++++++++++++++++- .../scala/internal/TupledFunction.scala | 104 ----------------- 3 files changed, 109 insertions(+), 106 deletions(-) delete mode 100644 library/src-3.x/scala/internal/TupledFunction.scala diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md index d5a2d2d79e4f..353e267ded3c 100644 --- a/docs/docs/reference/other-new-features/tupled-function.md +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -17,7 +17,7 @@ The type class `TupleFunction` provides a way to abstract directly over function * @tparam G a tupled function type (function of arity 1 receiving a tuple as argument) */ @implicitNotFound("${F} cannot be tupled as ${G}") -trait TupledFunction[F, G] { +sealed trait TupledFunction[F, G] { def apply(f: F): G } ``` diff --git a/library/src-3.x/scala/TupledFunction.scala b/library/src-3.x/scala/TupledFunction.scala index 577c089f11bc..aaec4ed5cabf 100644 --- a/library/src-3.x/scala/TupledFunction.scala +++ b/library/src-3.x/scala/TupledFunction.scala @@ -8,6 +8,113 @@ import scala.annotation.implicitNotFound * @tparam G a tupled function type (function of arity 1 receiving a tuple as argument) */ @implicitNotFound("${F} cannot be tupled as ${G}") -trait TupledFunction[F, G] { +sealed trait TupledFunction[F, G] { def apply(f: F): G } + +package internal { + + object TupledFunction { + + def tupledFunction0[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = + ((args: Unit) => f.asInstanceOf[() => Any].apply()).asInstanceOf[G] + } + + def tupledFunction1[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = + ((args: Tuple1[Any]) => f.asInstanceOf[Any => Any].apply(args._1)).asInstanceOf[G] + } + + def tupledFunction2[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function2[_, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction3[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function3[_, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction4[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function4[_, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction5[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function5[_, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction6[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function6[_, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction7[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function7[_, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction8[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function8[_, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction9[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function9[_, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction10[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function10[_, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction11[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function11[_, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction12[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function12[_, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction13[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function13[_, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction14[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction15[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction16[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction17[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction18[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction19[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction20[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction21[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunction22[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = f.asInstanceOf[Function22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + } + + def tupledFunctionXXL[F, G]: TupledFunction[F, G] = new TupledFunction { + def apply(f: F): G = + ((args: TupleXXL) => f.asInstanceOf[FunctionXXL].apply(args.elems)).asInstanceOf[G] + } + + } + +} \ No newline at end of file diff --git a/library/src-3.x/scala/internal/TupledFunction.scala b/library/src-3.x/scala/internal/TupledFunction.scala deleted file mode 100644 index 2c787fbb92d5..000000000000 --- a/library/src-3.x/scala/internal/TupledFunction.scala +++ /dev/null @@ -1,104 +0,0 @@ -package scala.internal - -object TupledFunction { - - def tupledFunction0[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = - ((args: Unit) => f.asInstanceOf[() => Any].apply()).asInstanceOf[G] - } - - def tupledFunction1[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = - ((args: Tuple1[Any]) => f.asInstanceOf[Any => Any].apply(args._1)).asInstanceOf[G] - } - - def tupledFunction2[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function2[_, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction3[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function3[_, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction4[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function4[_, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction5[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function5[_, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction6[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function6[_, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction7[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function7[_, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction8[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function8[_, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction9[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function9[_, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction10[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function10[_, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction11[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function11[_, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction12[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function12[_, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction13[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function13[_, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction14[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction15[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction16[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction17[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction18[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction19[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction20[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction21[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunction22[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - } - - def tupledFunctionXXL[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = - ((args: TupleXXL) => f.asInstanceOf[FunctionXXL].apply(args.elems)).asInstanceOf[G] - } - -} From a5797562314622331539fd4f28ab30e2f6171c31 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 28 May 2019 14:30:34 +0200 Subject: [PATCH 11/14] Rename `TupledFunction.apply` to `TupledFunction.tuple` --- .../other-new-features/tupled-function.md | 8 +-- library/src-3.x/scala/TupledFunction.scala | 50 +++++++++---------- tests/run/tupled-function-andThen.scala | 2 +- tests/run/tupled-function-apply.scala | 4 +- tests/run/tupled-function-compose.scala | 2 +- .../tupled-function-extension-method.scala | 8 +-- tests/run/tupled-function-tupled.scala | 4 +- 7 files changed, 39 insertions(+), 39 deletions(-) diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md index 353e267ded3c..bb4cef6fb978 100644 --- a/docs/docs/reference/other-new-features/tupled-function.md +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -18,7 +18,7 @@ The type class `TupleFunction` provides a way to abstract directly over function */ @implicitNotFound("${F} cannot be tupled as ${G}") sealed trait TupledFunction[F, G] { - def apply(f: F): G + def tuple(f: F): G } ``` @@ -41,7 +41,7 @@ Examples * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F */ -def (f: F) tupled[F, Args <: Tuple, R] given (tupled: TupledFunction[F, Args => R]): Args => R = tupled(f) +def (f: F) tupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): Args => R = tf.tuple(f) ``` `TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/lampepfl/dotty/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/lampepfl/dotty/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples. @@ -55,7 +55,7 @@ def (f: F) tupled[F, Args <: Tuple, R] given (tupled: TupledFunction[F, Args => * @tparam GArgs the tuple type with the same types as the function arguments of G * @tparam R the return type of F */ -def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given (tupledG: TupledFunction[G, GArgs => FArgs], tupledF: TupledFunction[F, FArgs => R]): GArgs => R = { - (x: GArgs) => tupledF(f)(tupledG(g)(x)) +def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given (tg: TupledFunction[G, GArgs => FArgs], tf: TupledFunction[F, FArgs => R]): GArgs => R = { + (x: GArgs) => tf.tuple(f)(tg.tuple(g)(x)) } ``` diff --git a/library/src-3.x/scala/TupledFunction.scala b/library/src-3.x/scala/TupledFunction.scala index aaec4ed5cabf..1d500d1ed23d 100644 --- a/library/src-3.x/scala/TupledFunction.scala +++ b/library/src-3.x/scala/TupledFunction.scala @@ -9,7 +9,7 @@ import scala.annotation.implicitNotFound */ @implicitNotFound("${F} cannot be tupled as ${G}") sealed trait TupledFunction[F, G] { - def apply(f: F): G + def tuple(f: F): G } package internal { @@ -17,101 +17,101 @@ package internal { object TupledFunction { def tupledFunction0[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = + def tuple(f: F): G = ((args: Unit) => f.asInstanceOf[() => Any].apply()).asInstanceOf[G] } def tupledFunction1[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = + def tuple(f: F): G = ((args: Tuple1[Any]) => f.asInstanceOf[Any => Any].apply(args._1)).asInstanceOf[G] } def tupledFunction2[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function2[_, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function2[_, _, _]].tupled.asInstanceOf[G] } def tupledFunction3[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function3[_, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function3[_, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction4[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function4[_, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function4[_, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction5[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function5[_, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function5[_, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction6[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function6[_, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function6[_, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction7[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function7[_, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function7[_, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction8[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function8[_, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function8[_, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction9[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function9[_, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function9[_, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction10[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function10[_, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function10[_, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction11[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function11[_, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function11[_, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction12[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function12[_, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function12[_, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction13[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function13[_, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function13[_, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction14[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction15[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction16[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction17[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction18[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction19[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction20[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction21[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunction22[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = f.asInstanceOf[Function22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def tuple(f: F): G = f.asInstanceOf[Function22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] } def tupledFunctionXXL[F, G]: TupledFunction[F, G] = new TupledFunction { - def apply(f: F): G = + def tuple(f: F): G = ((args: TupleXXL) => f.asInstanceOf[FunctionXXL].apply(args.elems)).asInstanceOf[G] } diff --git a/tests/run/tupled-function-andThen.scala b/tests/run/tupled-function-andThen.scala index aef16590c844..0d230dbe8032 100644 --- a/tests/run/tupled-function-andThen.scala +++ b/tests/run/tupled-function-andThen.scala @@ -33,7 +33,7 @@ object Test { * @tparam R the return type of G */ def (f: F) andThen[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given (tf: TupledFunction[F, FArgs => GArgs], tg: TupledFunction[G, GArgs => R]): FArgs => R = { - x => tg(g)(tf(f)(x)) + x => tg.tuple(g)(tf.tuple(f)(x)) } } diff --git a/tests/run/tupled-function-apply.scala b/tests/run/tupled-function-apply.scala index 71af04efc293..f424147655b2 100644 --- a/tests/run/tupled-function-apply.scala +++ b/tests/run/tupled-function-apply.scala @@ -113,6 +113,6 @@ object Test { * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F */ - def (f: F) apply[F, Args <: Tuple, R](args: Args) given (tupled: TupledFunction[F, Args => R]): R = - tupled(f)(args) + def (f: F) apply[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, Args => R]): R = + tf.tuple(f)(args) } \ No newline at end of file diff --git a/tests/run/tupled-function-compose.scala b/tests/run/tupled-function-compose.scala index d4ff04512bad..3f8b7d743b6e 100644 --- a/tests/run/tupled-function-compose.scala +++ b/tests/run/tupled-function-compose.scala @@ -34,7 +34,7 @@ object Test { * @tparam R the return type of F */ def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given (tg: TupledFunction[G, GArgs => FArgs], tf: TupledFunction[F, FArgs => R]): GArgs => R = { - x => tf(f)(tg(g)(x)) + x => tf.tuple(f)(tg.tuple(g)(x)) } } diff --git a/tests/run/tupled-function-extension-method.scala b/tests/run/tupled-function-extension-method.scala index b459f78f5361..28f5ebc3b2d2 100644 --- a/tests/run/tupled-function-extension-method.scala +++ b/tests/run/tupled-function-extension-method.scala @@ -39,9 +39,9 @@ object Test { def (e: Expr[given Arg => R]) applyGiven[Arg, R](arg: Arg): R = e.x given arg // Applied to all funtions of arity 2 or more (including more than 22 parameters) - def (e: Expr[F]) apply[F, Args <: Tuple, R](args: Args) given (tupled: TupledFunction[F, Args => R]): R = - tupled(e.x)(args) - def (e: Expr[F]) applyGiven[F, Args <: Tuple, R](args: Args) given (tupled: TupledFunction[F, given Args => R]): R = - tupled(e.x) given args + def (e: Expr[F]) apply[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, Args => R]): R = + tf.tuple(e.x)(args) + def (e: Expr[F]) applyGiven[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, given Args => R]): R = + tf.tuple(e.x) given args } \ No newline at end of file diff --git a/tests/run/tupled-function-tupled.scala b/tests/run/tupled-function-tupled.scala index e22cde095db9..61bd91eff693 100644 --- a/tests/run/tupled-function-tupled.scala +++ b/tests/run/tupled-function-tupled.scala @@ -24,5 +24,5 @@ object Test { * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F */ - def (f: F) tupled[F, Args <: Tuple, R] given (tupled: TupledFunction[F, Args => R]): Args => R = tupled(f) -} \ No newline at end of file + def (f: F) tupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): Args => R = tf.tuple(f) +} From 9f02e64928f6b48747a5b501566fb576804f50f0 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 28 May 2019 16:21:09 +0200 Subject: [PATCH 12/14] Add TupledFunction.untuple Also improve type inference of TupledFunction[F, G] when F is not yet inferred --- .../dotty/tools/dotc/core/Definitions.scala | 13 +++ .../dotty/tools/dotc/typer/Implicits.scala | 55 ++++++--- library/src-3.x/scala/TupledFunction.scala | 70 +++++++++++- tests/run/tupled-function-untupled.scala | 108 ++++++++++++++++++ 4 files changed, 223 insertions(+), 23 deletions(-) create mode 100644 tests/run/tupled-function-untupled.scala diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 51d64b248bb9..f24bc65b7ae1 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -10,6 +10,8 @@ import collection.mutable import Denotations.SingleDenotation import util.SimpleIdentityMap +import scala.annotation.tailrec + object Definitions { /** The maximum number of elements in a tuple or product. @@ -1198,6 +1200,17 @@ class Definitions { else TypeOps.nestedPairs(elems) } + def tupleTypes(tp: Type, bound: Int = Int.MaxValue)(implicit ctx: Context): Option[List[Type]] = { + @tailrec def rec(tp: Type, acc: List[Type], bound: Int): Option[List[Type]] = tp match { + case _ if bound < 0 => Some(acc.reverse) + case tp: AppliedType if defn.PairClass == tp.classSymbol => rec(tp.args(1), tp.args.head :: acc, bound - 1) + case tp: AppliedType if defn.isTupleClass(tp.tycon.classSymbol) => Some(acc.reverse ::: tp.args) + case tp if tp.classSymbol == defn.UnitClass => Some(acc.reverse) + case _ => None + } + rec(tp.stripTypeVar, Nil, bound) + } + def isProductSubType(tp: Type)(implicit ctx: Context): Boolean = tp.derivesFrom(ProductType.symbol) diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 430658acae72..af7d0c31d621 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -711,23 +711,44 @@ trait Implicits { self: Typer => def synthesizedTupleFunction(formal: Type): Tree = { formal match { - case AppliedType(_, funArgs @ fun :: tupled :: Nil) if defn.isFunctionType(fun) && defn.isFunctionType(tupled) => - lazy val funTypes = fun.dropDependentRefinement.dealias.argInfos - lazy val tupledTypes = tupled.dropDependentRefinement.dealias.argInfos - if ( - defn.isImplicitFunctionType(fun) == defn.isImplicitFunctionType(tupled) && - tupledTypes.size == 2 && - defn.tupleType(funTypes.init) =:= tupledTypes.head && - funTypes.last =:= tupledTypes.last - ) { - val arity = funTypes.size - 1 - if (defn.isErasedFunctionType(fun)) - EmptyTree // TODO support? - else if (arity <= Definitions.MaxImplementedFunctionArity) - ref(defn.InternalTupleFunctionModule).select(s"tupledFunction$arity".toTermName).appliedToTypes(funArgs) - else - ref(defn.InternalTupleFunctionModule).select("tupledFunctionXXL".toTermName).appliedToTypes(funArgs) - } else EmptyTree + case AppliedType(_, funArgs @ fun :: tupled :: Nil) => + def functionTypeEqual(baseFun: Type, actualArgs: List[Type], actualRet: Type, expected: Type) = { + expected =:= defn.FunctionOf(actualArgs, actualRet, defn.isImplicitFunctionType(baseFun), defn.isErasedFunctionType(baseFun)) + } + val arity: Int = { + if (defn.isErasedFunctionType(fun) || defn.isErasedFunctionType(fun)) -1 // TODO support? + else if (defn.isFunctionType(fun)) { + // TupledFunction[(...) => R, ?] + fun.dropDependentRefinement.dealias.argInfos match { + case funArgs :+ funRet if functionTypeEqual(fun, defn.tupleType(funArgs) :: Nil, funRet, tupled) => + // TupledFunction[(...funArgs...) => funRet, ?] + funArgs.size + case _ => -1 + } + } else if (defn.isFunctionType(tupled)) { + // TupledFunction[?, (...) => R] + tupled.dropDependentRefinement.dealias.argInfos match { + case tupledArgs :: funRet :: Nil => + defn.tupleTypes(tupledArgs) match { + case Some(funArgs) if functionTypeEqual(tupled, funArgs, funRet, fun) => + // TupledFunction[?, ((...funArgs...)) => funRet] + funArgs.size + case _ => -1 + } + case _ => -1 + } + } + else { + // TupledFunction[?, ?] + -1 + } + } + if (arity == -1) + EmptyTree + else if (arity <= Definitions.MaxImplementedFunctionArity) + ref(defn.InternalTupleFunctionModule).select(s"tupledFunction$arity".toTermName).appliedToTypes(funArgs) + else + ref(defn.InternalTupleFunctionModule).select("tupledFunctionXXL".toTermName).appliedToTypes(funArgs) case _ => EmptyTree } diff --git a/library/src-3.x/scala/TupledFunction.scala b/library/src-3.x/scala/TupledFunction.scala index 1d500d1ed23d..c15e63c1b4fc 100644 --- a/library/src-3.x/scala/TupledFunction.scala +++ b/library/src-3.x/scala/TupledFunction.scala @@ -10,6 +10,7 @@ import scala.annotation.implicitNotFound @implicitNotFound("${F} cannot be tupled as ${G}") sealed trait TupledFunction[F, G] { def tuple(f: F): G + def untuple(g: G): F } package internal { @@ -17,102 +18,159 @@ package internal { object TupledFunction { def tupledFunction0[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = - ((args: Unit) => f.asInstanceOf[() => Any].apply()).asInstanceOf[G] + def tuple(f: F): G = ((args: Unit) => f.asInstanceOf[() => Any].apply()).asInstanceOf[G] + def untuple(g: G): F = (() => g.asInstanceOf[Unit => Any].apply(())).asInstanceOf[F] } def tupledFunction1[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = - ((args: Tuple1[Any]) => f.asInstanceOf[Any => Any].apply(args._1)).asInstanceOf[G] + def tuple(f: F): G = ((args: Tuple1[Any]) => f.asInstanceOf[Any => Any].apply(args._1)).asInstanceOf[G] + def untuple(g: G): F = ((x1: Any) => g.asInstanceOf[Tuple1[_] => Any].apply(Tuple1(x1))).asInstanceOf[F] } def tupledFunction2[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function2[_, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = Function.untupled(g.asInstanceOf[Tuple2[_, _] => Any]).asInstanceOf[F] } def tupledFunction3[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function3[_, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = Function.untupled(g.asInstanceOf[Tuple3[_, _, _] => Any]).asInstanceOf[F] } def tupledFunction4[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function4[_, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = Function.untupled(g.asInstanceOf[Tuple4[_, _, _, _] => Any]).asInstanceOf[F] } def tupledFunction5[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function5[_, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = Function.untupled(g.asInstanceOf[Tuple5[_, _, _, _, _] => Any]).asInstanceOf[F] } def tupledFunction6[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function6[_, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) => + g.asInstanceOf[Tuple6[_, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6))).asInstanceOf[F] } def tupledFunction7[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function7[_, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) => + g.asInstanceOf[Tuple7[_, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7))).asInstanceOf[F] } def tupledFunction8[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function8[_, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) => + g.asInstanceOf[Tuple8[_, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8))).asInstanceOf[F] } def tupledFunction9[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function9[_, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) => + g.asInstanceOf[Tuple9[_, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9))).asInstanceOf[F] } def tupledFunction10[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function10[_, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) => + g.asInstanceOf[Tuple10[_, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10))).asInstanceOf[F] } def tupledFunction11[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function11[_, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) => + g.asInstanceOf[Tuple11[_, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11))).asInstanceOf[F] } def tupledFunction12[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function12[_, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) => + g.asInstanceOf[Tuple12[_, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12))).asInstanceOf[F] } def tupledFunction13[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function13[_, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) => + g.asInstanceOf[Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13))).asInstanceOf[F] } def tupledFunction14[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) => + g.asInstanceOf[Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14))).asInstanceOf[F] } def tupledFunction15[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) => + g.asInstanceOf[Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15))).asInstanceOf[F] } def tupledFunction16[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) => + g.asInstanceOf[Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16))).asInstanceOf[F] } def tupledFunction17[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) => + g.asInstanceOf[Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17))).asInstanceOf[F] } def tupledFunction18[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) => + g.asInstanceOf[Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18))).asInstanceOf[F] } def tupledFunction19[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) => + g.asInstanceOf[Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19))).asInstanceOf[F] } def tupledFunction20[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) => + g.asInstanceOf[Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20))).asInstanceOf[F] } def tupledFunction21[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) => + g.asInstanceOf[Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21))).asInstanceOf[F] } def tupledFunction22[F, G]: TupledFunction[F, G] = new TupledFunction { def tuple(f: F): G = f.asInstanceOf[Function22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untuple(g: G): F = + ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any, x22: Any) => + g.asInstanceOf[Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22))).asInstanceOf[F] } def tupledFunctionXXL[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = - ((args: TupleXXL) => f.asInstanceOf[FunctionXXL].apply(args.elems)).asInstanceOf[G] + def tuple(f: F): G = ((args: TupleXXL) => f.asInstanceOf[FunctionXXL].apply(args.elems)).asInstanceOf[G] + def untuple(g: G): F = new FunctionXXL { + override def apply(xs: Array[Object]): AnyRef = g.asInstanceOf[TupleXXL => AnyRef].apply(TupleXXL(xs)) + }.asInstanceOf[F] } } diff --git a/tests/run/tupled-function-untupled.scala b/tests/run/tupled-function-untupled.scala new file mode 100644 index 000000000000..9575e992df4c --- /dev/null +++ b/tests/run/tupled-function-untupled.scala @@ -0,0 +1,108 @@ +object Test { + def main(args: Array[String]): Unit = { + + val f0 = (args: Unit) => 0 + val g0: () => Int = f0.untupled + println(g0()) + + val f1 = (args: Tuple1[Int]) => 1 + val g1: (Int) => Int = f1.untupled + println(g1(1)) + + val f2 = (args: (Int, Int)) => 2 + val g2: (Int, Int) => Int = f2.untupled + println(g2(1, 2)) + + val f3 = (args: (Int, Int, Int)) => 3 + val g3: (Int, Int, Int) => Int = f3.untupled + println(g3(1, 2, 3)) + + val f4 = (args: (Int, Int, Int, Int)) => 4 + val g4: (Int, Int, Int, Int) => Int = f4.untupled + println(g4(1, 2, 3, 4)) + + val f5 = (args: (Int, Int, Int, Int, Int)) => 5 + val g5: (Int, Int, Int, Int, Int) => Int = f5.untupled + println(g5(1, 2, 3, 4, 5)) + + val f6 = (args: (Int, Int, Int, Int, Int, Int)) => 6 + val g6: (Int, Int, Int, Int, Int, Int) => Int = f6.untupled + println(g6(1, 2, 3, 4, 5, 6)) + + val f7 = (args: (Int, Int, Int, Int, Int, Int, Int)) => 7 + val g7: (Int, Int, Int, Int, Int, Int, Int) => Int = f7.untupled + println(g7(1, 2, 3, 4, 5, 6, 7)) + + val f8 = (args: (Int, Int, Int, Int, Int, Int, Int, Int)) => 8 + val g8: (Int, Int, Int, Int, Int, Int, Int, Int) => Int = f8.untupled + println(g8(1, 2, 3, 4, 5, 6, 7, 8)) + + val f9 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 9 + val g9: (Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f9.untupled + println(g9(1, 2, 3, 4, 5, 6, 7, 8, 9)) + + val f10 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 10 + val g10: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f10.untupled + println(g10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) + + val f11 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 11 + val g11: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f11.untupled + println(g11(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)) + + val f12 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 12 + val g12: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f12.untupled + println(g12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)) + + val f13 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 13 + val g13: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f13.untupled + println(g13(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)) + + val f14 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 14 + val g14: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f14.untupled + println(g14(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)) + + val f15 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 15 + val g15: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f15.untupled + println(g15(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)) + + val f16 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 16 + val g16: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f16.untupled + println(g16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)) + + val f17 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 17 + val g17: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f17.untupled + println(g17(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)) + + val f18 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 18 + val g18: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f18.untupled + println(g18(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)) + + val f19 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 19 + val g19: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f19.untupled + println(g19(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)) + + val f20 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 20 + val g20: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f20.untupled + println(g20(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)) + + val f21 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 21 + val g21: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f21.untupled + println(g21(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)) + + val f22 = (args: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)) => 22 + val g22: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) => Int = f22.untupled + println(g22(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)) + + } + + /** Creates an untupled version of this function: instead of single [[scala.Tuple]] argument, + * it accepts a N arguments. + * + * This is a generalization of [[scala.Function.untupled]] that work on functions of any arity + * + * @tparam F the function type + * @tparam Args the tuple type with the same types as the function arguments of F + * @tparam R the return type of F + */ + def (f: Args => R) untupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): F = tf.untuple(f) +} From 5e209f54b90fa87bfb80df2d452daa44793fcaac Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 28 May 2019 17:02:56 +0200 Subject: [PATCH 13/14] Update docs --- .../other-new-features/tupled-function.md | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md index bb4cef6fb978..6210890cbfb0 100644 --- a/docs/docs/reference/other-new-features/tupled-function.md +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -8,7 +8,7 @@ Tupled Function With functions bounded to arities up to 22 it was possible to generalize some operation on all function types using overloading. Now that we have functions and tuples generalized to [arities above 22](https://dotty.epfl.ch/docs/reference/dropped-features/limit22.html) overloading is not an option anymore. -The type class `TupleFunction` provides a way to abstract directly over functions of any arity converting it to an equivalent function that receives all arguments in a single tuple. +The type class `TupleFunction` provides a way to abstract directly over a function of any arity converting it to an equivalent function that receives all arguments in a single tuple. ```scala /** Type class relating a `FunctionN[..., R]` with an equvalent tupled function `Function1[TupleN[...], R]` @@ -19,6 +19,7 @@ The type class `TupleFunction` provides a way to abstract directly over function @implicitNotFound("${F} cannot be tupled as ${G}") sealed trait TupledFunction[F, G] { def tuple(f: F): G + def untuple(g: G): F } ``` @@ -27,11 +28,12 @@ The compiler will synthesize an instance of `TupledFunction[F, G]` if: * `F` is a function type of arity `N` * `G` is a function with a single tuple argument of size `N` and it's types are equal to the arguments of `F` * The return type of `F` is equal to the return type of `G` -* `F` and `G` are the same kind of functions (`given` arguments or not) +* `F` and `G` are the same kind of function (both are `(...) => R` or both are `given (...) => R`) +* If only one of `F` or `G` is instantiated the second one is inferred. Examples -------- -`TupledFunction` can be used to generalize the `Tuple2.tupled`, ... `Tuple22.tupled` method to functions of any arities ([full example](https://github.com/lampepfl/dotty/tests/run/tupled-function-tupled.scala)) +`TupledFunction` can be used to generalize the `Function1.tupled`, ... `Function22.tupled` methods to functions of any arities ([full example](https://github.com/lampepfl/dotty/tests/run/tupled-function-tupled.scala)) ```scala /** Creates a tupled version of this function: instead of N arguments, @@ -44,6 +46,21 @@ Examples def (f: F) tupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): Args => R = tf.tuple(f) ``` +`TupledFunction` can be used to generalize the `Function.untupled` methods to functions of any arities ([full example](https://github.com/lampepfl/dotty/tests/run/tupled-function-untupled.scala)) + +```scala +/** Creates an untupled version of this function: instead of single [[scala.Tuple]] argument, + * it accepts a N arguments. + * + * This is a generalization of [[scala.Function.untupled]] that work on functions of any arity + * + * @tparam F the function type + * @tparam Args the tuple type with the same types as the function arguments of F + * @tparam R the return type of F + */ +def (f: Args => R) untupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): F = tf.untuple(f) +``` + `TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/lampepfl/dotty/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/lampepfl/dotty/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples. ```scala From 9507c1f13c05cb8bbea1e30e3f1ea8fd065bebf4 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 28 May 2019 17:22:28 +0200 Subject: [PATCH 14/14] Rename TupledFunction.{tuple|untuple} to tupled and untupled To have the same naming convention as scala.Function.{tupled|untupled} --- .../other-new-features/tupled-function.md | 12 +-- library/src-3.x/scala/TupledFunction.scala | 102 +++++++++--------- tests/run/tupled-function-andThen.scala | 2 +- tests/run/tupled-function-apply.scala | 2 +- tests/run/tupled-function-compose.scala | 2 +- .../tupled-function-extension-method.scala | 4 +- tests/run/tupled-function-tupled.scala | 2 +- tests/run/tupled-function-untupled.scala | 2 +- 8 files changed, 64 insertions(+), 64 deletions(-) diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md index 6210890cbfb0..fa7d94f36951 100644 --- a/docs/docs/reference/other-new-features/tupled-function.md +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -11,15 +11,15 @@ Now that we have functions and tuples generalized to [arities above 22](https:// The type class `TupleFunction` provides a way to abstract directly over a function of any arity converting it to an equivalent function that receives all arguments in a single tuple. ```scala -/** Type class relating a `FunctionN[..., R]` with an equvalent tupled function `Function1[TupleN[...], R]` +/** Type class relating a `FunctionN[..., R]` with an equivalent tupled function `Function1[TupleN[...], R]` * * @tparam F a function type * @tparam G a tupled function type (function of arity 1 receiving a tuple as argument) */ @implicitNotFound("${F} cannot be tupled as ${G}") sealed trait TupledFunction[F, G] { - def tuple(f: F): G - def untuple(g: G): F + def tupled(f: F): G + def untupled(g: G): F } ``` @@ -43,7 +43,7 @@ Examples * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F */ -def (f: F) tupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): Args => R = tf.tuple(f) +def (f: F) tupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): Args => R = tf.tupled(f) ``` `TupledFunction` can be used to generalize the `Function.untupled` methods to functions of any arities ([full example](https://github.com/lampepfl/dotty/tests/run/tupled-function-untupled.scala)) @@ -58,7 +58,7 @@ def (f: F) tupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F */ -def (f: Args => R) untupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): F = tf.untuple(f) +def (f: Args => R) untupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): F = tf.untupled(f) ``` `TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/lampepfl/dotty/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/lampepfl/dotty/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples. @@ -73,6 +73,6 @@ def (f: Args => R) untupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Ar * @tparam R the return type of F */ def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given (tg: TupledFunction[G, GArgs => FArgs], tf: TupledFunction[F, FArgs => R]): GArgs => R = { - (x: GArgs) => tf.tuple(f)(tg.tuple(g)(x)) + (x: GArgs) => tf.tupled(f)(tg.tupled(g)(x)) } ``` diff --git a/library/src-3.x/scala/TupledFunction.scala b/library/src-3.x/scala/TupledFunction.scala index c15e63c1b4fc..ceba68089b8c 100644 --- a/library/src-3.x/scala/TupledFunction.scala +++ b/library/src-3.x/scala/TupledFunction.scala @@ -2,15 +2,15 @@ package scala import scala.annotation.implicitNotFound -/** Type class relating a `FunctionN[..., R]` with an equvalent tupled function `Function1[TupleN[...], R]` +/** Type class relating a `FunctionN[..., R]` with an equivalent tupled function `Function1[TupleN[...], R]` * * @tparam F a function type * @tparam G a tupled function type (function of arity 1 receiving a tuple as argument) */ @implicitNotFound("${F} cannot be tupled as ${G}") sealed trait TupledFunction[F, G] { - def tuple(f: F): G - def untuple(g: G): F + def tupled(f: F): G + def untupled(g: G): F } package internal { @@ -18,157 +18,157 @@ package internal { object TupledFunction { def tupledFunction0[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = ((args: Unit) => f.asInstanceOf[() => Any].apply()).asInstanceOf[G] - def untuple(g: G): F = (() => g.asInstanceOf[Unit => Any].apply(())).asInstanceOf[F] + def tupled(f: F): G = ((args: Unit) => f.asInstanceOf[() => Any].apply()).asInstanceOf[G] + def untupled(g: G): F = (() => g.asInstanceOf[Unit => Any].apply(())).asInstanceOf[F] } def tupledFunction1[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = ((args: Tuple1[Any]) => f.asInstanceOf[Any => Any].apply(args._1)).asInstanceOf[G] - def untuple(g: G): F = ((x1: Any) => g.asInstanceOf[Tuple1[_] => Any].apply(Tuple1(x1))).asInstanceOf[F] + def tupled(f: F): G = ((args: Tuple1[Any]) => f.asInstanceOf[Any => Any].apply(args._1)).asInstanceOf[G] + def untupled(g: G): F = ((x1: Any) => g.asInstanceOf[Tuple1[_] => Any].apply(Tuple1(x1))).asInstanceOf[F] } def tupledFunction2[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function2[_, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = Function.untupled(g.asInstanceOf[Tuple2[_, _] => Any]).asInstanceOf[F] + def tupled(f: F): G = f.asInstanceOf[Function2[_, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = Function.untupled(g.asInstanceOf[Tuple2[_, _] => Any]).asInstanceOf[F] } def tupledFunction3[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function3[_, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = Function.untupled(g.asInstanceOf[Tuple3[_, _, _] => Any]).asInstanceOf[F] + def tupled(f: F): G = f.asInstanceOf[Function3[_, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = Function.untupled(g.asInstanceOf[Tuple3[_, _, _] => Any]).asInstanceOf[F] } def tupledFunction4[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function4[_, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = Function.untupled(g.asInstanceOf[Tuple4[_, _, _, _] => Any]).asInstanceOf[F] + def tupled(f: F): G = f.asInstanceOf[Function4[_, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = Function.untupled(g.asInstanceOf[Tuple4[_, _, _, _] => Any]).asInstanceOf[F] } def tupledFunction5[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function5[_, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = Function.untupled(g.asInstanceOf[Tuple5[_, _, _, _, _] => Any]).asInstanceOf[F] + def tupled(f: F): G = f.asInstanceOf[Function5[_, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = Function.untupled(g.asInstanceOf[Tuple5[_, _, _, _, _] => Any]).asInstanceOf[F] } def tupledFunction6[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function6[_, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function6[_, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) => g.asInstanceOf[Tuple6[_, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6))).asInstanceOf[F] } def tupledFunction7[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function7[_, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function7[_, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) => g.asInstanceOf[Tuple7[_, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7))).asInstanceOf[F] } def tupledFunction8[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function8[_, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function8[_, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) => g.asInstanceOf[Tuple8[_, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8))).asInstanceOf[F] } def tupledFunction9[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function9[_, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function9[_, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) => g.asInstanceOf[Tuple9[_, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9))).asInstanceOf[F] } def tupledFunction10[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function10[_, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function10[_, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) => g.asInstanceOf[Tuple10[_, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10))).asInstanceOf[F] } def tupledFunction11[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function11[_, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function11[_, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) => g.asInstanceOf[Tuple11[_, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11))).asInstanceOf[F] } def tupledFunction12[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function12[_, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function12[_, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) => g.asInstanceOf[Tuple12[_, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12))).asInstanceOf[F] } def tupledFunction13[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function13[_, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function13[_, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) => g.asInstanceOf[Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13))).asInstanceOf[F] } def tupledFunction14[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) => g.asInstanceOf[Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14))).asInstanceOf[F] } def tupledFunction15[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) => g.asInstanceOf[Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15))).asInstanceOf[F] } def tupledFunction16[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) => g.asInstanceOf[Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16))).asInstanceOf[F] } def tupledFunction17[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) => g.asInstanceOf[Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17))).asInstanceOf[F] } def tupledFunction18[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) => g.asInstanceOf[Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18))).asInstanceOf[F] } def tupledFunction19[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) => g.asInstanceOf[Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19))).asInstanceOf[F] } def tupledFunction20[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) => g.asInstanceOf[Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20))).asInstanceOf[F] } def tupledFunction21[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) => g.asInstanceOf[Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21))).asInstanceOf[F] } def tupledFunction22[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = f.asInstanceOf[Function22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] - def untuple(g: G): F = + def tupled(f: F): G = f.asInstanceOf[Function22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]].tupled.asInstanceOf[G] + def untupled(g: G): F = ((x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any, x22: Any) => g.asInstanceOf[Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => Any].apply((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22))).asInstanceOf[F] } def tupledFunctionXXL[F, G]: TupledFunction[F, G] = new TupledFunction { - def tuple(f: F): G = ((args: TupleXXL) => f.asInstanceOf[FunctionXXL].apply(args.elems)).asInstanceOf[G] - def untuple(g: G): F = new FunctionXXL { + def tupled(f: F): G = ((args: TupleXXL) => f.asInstanceOf[FunctionXXL].apply(args.elems)).asInstanceOf[G] + def untupled(g: G): F = new FunctionXXL { override def apply(xs: Array[Object]): AnyRef = g.asInstanceOf[TupleXXL => AnyRef].apply(TupleXXL(xs)) }.asInstanceOf[F] } diff --git a/tests/run/tupled-function-andThen.scala b/tests/run/tupled-function-andThen.scala index 0d230dbe8032..39c22262f2a7 100644 --- a/tests/run/tupled-function-andThen.scala +++ b/tests/run/tupled-function-andThen.scala @@ -33,7 +33,7 @@ object Test { * @tparam R the return type of G */ def (f: F) andThen[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given (tf: TupledFunction[F, FArgs => GArgs], tg: TupledFunction[G, GArgs => R]): FArgs => R = { - x => tg.tuple(g)(tf.tuple(f)(x)) + x => tg.tupled(g)(tf.tupled(f)(x)) } } diff --git a/tests/run/tupled-function-apply.scala b/tests/run/tupled-function-apply.scala index f424147655b2..015d2bade219 100644 --- a/tests/run/tupled-function-apply.scala +++ b/tests/run/tupled-function-apply.scala @@ -114,5 +114,5 @@ object Test { * @tparam R the return type of F */ def (f: F) apply[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, Args => R]): R = - tf.tuple(f)(args) + tf.tupled(f)(args) } \ No newline at end of file diff --git a/tests/run/tupled-function-compose.scala b/tests/run/tupled-function-compose.scala index 3f8b7d743b6e..e077e4d439f0 100644 --- a/tests/run/tupled-function-compose.scala +++ b/tests/run/tupled-function-compose.scala @@ -34,7 +34,7 @@ object Test { * @tparam R the return type of F */ def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G) given (tg: TupledFunction[G, GArgs => FArgs], tf: TupledFunction[F, FArgs => R]): GArgs => R = { - x => tf.tuple(f)(tg.tuple(g)(x)) + x => tf.tupled(f)(tg.tupled(g)(x)) } } diff --git a/tests/run/tupled-function-extension-method.scala b/tests/run/tupled-function-extension-method.scala index 28f5ebc3b2d2..352f784771e2 100644 --- a/tests/run/tupled-function-extension-method.scala +++ b/tests/run/tupled-function-extension-method.scala @@ -40,8 +40,8 @@ object Test { // Applied to all funtions of arity 2 or more (including more than 22 parameters) def (e: Expr[F]) apply[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, Args => R]): R = - tf.tuple(e.x)(args) + tf.tupled(e.x)(args) def (e: Expr[F]) applyGiven[F, Args <: Tuple, R](args: Args) given (tf: TupledFunction[F, given Args => R]): R = - tf.tuple(e.x) given args + tf.tupled(e.x) given args } \ No newline at end of file diff --git a/tests/run/tupled-function-tupled.scala b/tests/run/tupled-function-tupled.scala index 61bd91eff693..5aa71bb3b1d0 100644 --- a/tests/run/tupled-function-tupled.scala +++ b/tests/run/tupled-function-tupled.scala @@ -24,5 +24,5 @@ object Test { * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F */ - def (f: F) tupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): Args => R = tf.tuple(f) + def (f: F) tupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): Args => R = tf.tupled(f) } diff --git a/tests/run/tupled-function-untupled.scala b/tests/run/tupled-function-untupled.scala index 9575e992df4c..dddffc88220a 100644 --- a/tests/run/tupled-function-untupled.scala +++ b/tests/run/tupled-function-untupled.scala @@ -104,5 +104,5 @@ object Test { * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F */ - def (f: Args => R) untupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): F = tf.untuple(f) + def (f: Args => R) untupled[F, Args <: Tuple, R] given (tf: TupledFunction[F, Args => R]): F = tf.untupled(f) }