From 33e3fe7868212cd50d561cde1e28fc69c4833858 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 6 Jun 2019 10:22:50 +0200 Subject: [PATCH 1/5] Support Expr.FunctionBetaReduction for all arities --- .../dotty/tools/dotc/core/Definitions.scala | 2 +- library/src-3.x/scala/quoted/Expr.scala | 281 +----------------- 2 files changed, 12 insertions(+), 271 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 0d02b50cb259..88ee0e46f19b 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -1232,7 +1232,7 @@ class Definitions { } 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 { + @tailrec def rec(tp: Type, acc: List[Type], bound: Int): Option[List[Type]] = tp.normalized 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) diff --git a/library/src-3.x/scala/quoted/Expr.scala b/library/src-3.x/scala/quoted/Expr.scala index a7cd41179407..f65d57f66ab9 100644 --- a/library/src-3.x/scala/quoted/Expr.scala +++ b/library/src-3.x/scala/quoted/Expr.scala @@ -21,280 +21,21 @@ package quoted { def show(implicit toolbox: Toolbox): String = toolbox.show(expr) } - implicit object FunctionBetaReduction { + type TupleOfExpr[Tup <: Tuple] <: Tuple = Tup match { + case Unit => Unit + case h *: t => Expr[h] *: TupleOfExpr[t] + } + implicit class FunctionBetaReduction[F, Args <: Tuple, R](f: Expr[F]) given (tf: TupledFunction[F, Args => R]) { /** Beta-reduces the function appication. Generates the an expression only containing the body of the function */ - def (f: Expr[() => R]) apply[R] (): Expr[R] = - new FunctionAppliedTo[R](f, Array.empty) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1) => R]) apply[T1, R](x1: Expr[T1]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2) => R]) apply[T1, T2, R](x1: Expr[T1], x2: Expr[T2]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3) => R]) apply[T1, T2, T3, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4) => R]) apply[T1, T2, T3, T4, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5) => R]) apply[T1, T2, T3, T4, T5, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6) => R]) apply[T1, T2, T3, T4, T5, T6, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7) => R]) apply[T1, T2, T3, T4, T5, T6, T7, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19], x20: Expr[T20]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19], x20: Expr[T20], x21: Expr[T21]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) - - /** Beta-reduces the function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19], x20: Expr[T20], x21: Expr[T21], x22: Expr[T22]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) - + def apply[G] given (tg: TupledFunction[G, TupleOfExpr[Args] => Expr[R]]): G = + tg.untupled(args => new FunctionAppliedTo[R](f, args.toArray.map(_.asInstanceOf[Expr[_]]))) } - implicit object ContextualFunctionBetaReduction { - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1) => R]) apply[T1, R](x1: Expr[T1]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2) => R]) apply[T1, T2, R](x1: Expr[T1], x2: Expr[T2]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3) => R]) apply[T1, T2, T3, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4) => R]) apply[T1, T2, T3, T4, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5) => R]) apply[T1, T2, T3, T4, T5, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6) => R]) apply[T1, T2, T3, T4, T5, T6, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7) => R]) apply[T1, T2, T3, T4, T5, T6, T7, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19], x20: Expr[T20]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19], x20: Expr[T20], x21: Expr[T21]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) - - /** Beta-reduces the contextual function appication. - * Generates the an expression that evaluates all arguments and then evaluates the body with the evaluated arguments - */ - def (f: Expr[given (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) => R]) apply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19], x20: Expr[T20], x21: Expr[T21], x22: Expr[T22]): Expr[R] = - new FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) - + implicit class ContextualFunctionBetaReduction[F, Args <: Tuple, R](f: Expr[F]) given (tf: TupledFunction[F, given Args => R]) { + /** Beta-reduces the function appication. Generates the an expression only containing the body of the function */ + def apply[G] given (tg: TupledFunction[G, TupleOfExpr[Args] => Expr[R]]): G = + tg.untupled(args => new FunctionAppliedTo[R](f, args.toArray.map(_.asInstanceOf[Expr[_]]))) } } From 14b41494d1fe0a455883cd591c9ccc013d128e60 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 6 Jun 2019 10:33:48 +0200 Subject: [PATCH 2/5] Factor out useful Tuple map type match --- compiler/src/dotty/tools/dotc/typer/Implicits.scala | 2 +- library/src-3.x/scala/Tuple.scala | 6 ++++++ library/src-3.x/scala/quoted/Expr.scala | 6 ++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index b1c4ec04dd1f..1cb2fa571985 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -719,7 +719,7 @@ trait Implicits { self: Typer => // TupledFunction[?, (...) => R] tupled.dropDependentRefinement.dealias.argInfos match { case tupledArgs :: funRet :: Nil => - defn.tupleTypes(tupledArgs) match { + defn.tupleTypes(tupledArgs.dealias) match { case Some(funArgs) if functionTypeEqual(tupled, funArgs, funRet, fun) => // TupledFunction[?, ((...funArgs...)) => funRet] funArgs.size diff --git a/library/src-3.x/scala/Tuple.scala b/library/src-3.x/scala/Tuple.scala index 91fdac7f46bf..24389c0747b7 100644 --- a/library/src-3.x/scala/Tuple.scala +++ b/library/src-3.x/scala/Tuple.scala @@ -64,6 +64,12 @@ object Tuple { case x *: xs => S[Size[xs]] } + /** Converts a tuple `(T1, ..., Tn)` to `(F[T1], ..., F[Tn])` */ + type Map[Tup <: Tuple, F[_]] <: Tuple = Tup match { + case Unit => Unit + case h *: t => F[h] *: Map[t, F] + } + /** Convert an array into a tuple of unknown arity and types */ def fromArray[T](xs: Array[T]): Tuple = { val xs2 = xs match { diff --git a/library/src-3.x/scala/quoted/Expr.scala b/library/src-3.x/scala/quoted/Expr.scala index f65d57f66ab9..e79f96212f25 100644 --- a/library/src-3.x/scala/quoted/Expr.scala +++ b/library/src-3.x/scala/quoted/Expr.scala @@ -21,10 +21,8 @@ package quoted { def show(implicit toolbox: Toolbox): String = toolbox.show(expr) } - type TupleOfExpr[Tup <: Tuple] <: Tuple = Tup match { - case Unit => Unit - case h *: t => Expr[h] *: TupleOfExpr[t] - } + /** Converts a tuple `(T1, ..., Tn)` to `(Expr[T1], ..., Expr[Tn])` */ + type TupleOfExpr[Tup <: Tuple] = Tuple.Map[Tup, Expr] implicit class FunctionBetaReduction[F, Args <: Tuple, R](f: Expr[F]) given (tf: TupledFunction[F, Args => R]) { /** Beta-reduces the function appication. Generates the an expression only containing the body of the function */ From 89be7da4efc4510503089d62e2913c4f4afaff0a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 6 Jun 2019 10:38:07 +0200 Subject: [PATCH 3/5] Remove duplicated logic --- .../dotc/transform/TupleOptimizations.scala | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/TupleOptimizations.scala b/compiler/src/dotty/tools/dotc/transform/TupleOptimizations.scala index 062d3d49120d..52f7db1482d6 100644 --- a/compiler/src/dotty/tools/dotc/transform/TupleOptimizations.scala +++ b/compiler/src/dotty/tools/dotc/transform/TupleOptimizations.scala @@ -36,7 +36,7 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer { private def transformTupleCons(tree: tpd.Apply)(implicit ctx: Context): Tree = { val head :: tail :: Nil = tree.args - tupleTypes(tree.tpe) match { + defn.tupleTypes(tree.tpe) match { case Some(tpes) => // Generate a the tuple directly with TupleN+1.apply val size = tpes.size @@ -64,7 +64,7 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer { private def transformTupleTail(tree: tpd.Apply)(implicit ctx: Context): Tree = { val Apply(TypeApply(_, tpt :: Nil), tup :: Nil) = tree - tupleTypes(tpt.tpe, MaxTupleArity + 1) match { + defn.tupleTypes(tpt.tpe, MaxTupleArity + 1) match { case Some(tpes) => // Generate a the tuple directly with TupleN-1.apply val size = tpes.size @@ -111,7 +111,7 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer { private def transformTupleConcat(tree: tpd.Apply)(implicit ctx: Context): Tree = { val Apply(TypeApply(_, selfTp :: thatTp :: Nil), self :: that :: Nil) = tree - (tupleTypes(selfTp.tpe), tupleTypes(that.tpe.widenTermRefExpr)) match { + (defn.tupleTypes(selfTp.tpe), defn.tupleTypes(that.tpe.widenTermRefExpr)) match { case (Some(tpes1), Some(tpes2)) => // Generate a the tuple directly with TupleN+M.apply val n = tpes1.size @@ -146,7 +146,7 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer { private def transformTupleApply(tree: tpd.Apply)(implicit ctx: Context): Tree = { val Apply(TypeApply(_, tpt :: nTpt :: Nil), tup :: nTree :: Nil) = tree - (tupleTypes(tpt.tpe), nTpt.tpe) match { + (defn.tupleTypes(tpt.tpe), nTpt.tpe) match { case (Some(tpes), nTpe: ConstantType) => // Get the element directly with TupleM._n+1 or TupleXXL.productElement(n) val size = tpes.size @@ -173,7 +173,7 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer { private def transformTupleToArray(tree: tpd.Apply)(implicit ctx: Context): Tree = { val Apply(_, tup :: Nil) = tree - tupleTypes(tup.tpe.widen, MaxTupleArity) match { + defn.tupleTypes(tup.tpe.widen, MaxTupleArity) match { case Some(tpes) => val size = tpes.size if (size == 0) { @@ -222,17 +222,6 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer { } } - private 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) - } - private def tupleSelectors(tup: Tree, size: Int)(implicit ctx: Context): List[Tree] = (0 until size).map(i => tup.select(nme.selectorName(i))).toList From e2546fc1dbc056b411c49fb33a158a32d31600e1 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 6 Jun 2019 13:12:43 +0200 Subject: [PATCH 4/5] Update documentation --- docs/docs/reference/metaprogramming/macros.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index 3f0a025798c4..681401890797 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -135,24 +135,24 @@ expressiveness. ### From `Expr`s to Functions and Back -The `Expr` companion object contains an implicit `AsFunctionN` (for 0 <= N < 23) conversion that turns a tree +The `Expr` companion object contains an implicit `FunctionBetaReduction` conversion that turns a tree describing a function into a function mapping trees to trees. ```scala object Expr { ... - implied AsFunction1[T, U] for Conversion[Expr[T => U], Expr[T] => Expr[U]] ... + implicit class FunctionBetaReduction[...](...) { ... } } ``` This decorator gives `Expr` the `apply` operation of an applicative functor, where `Expr`s over function types can be applied to `Expr` arguments. The definition -of `AsFunction1(f).apply(x)` is assumed to be functionally the same as +of `FunctionBetaReduction(f).apply(x)` is assumed to be functionally the same as `'{($f)($x)}`, however it should optimize this call by returning the result of beta-reducing `f(x)` if `f` is a known lambda expression. -The `AsFunction1` decorator distributes applications of `Expr` over function +The `FunctionBetaReduction` decorator distributes applications of `Expr` over function arrows: ```scala - AsFunction1(_).apply: Expr[S => T] => (Expr[S] => Expr[T]) + FunctionBetaReduction(f).apply: Expr[S => T] => (Expr[S] => Expr[T]) ``` Its dual, let’s call it `reflect`, can be defined as follows: ```scala From fb54ac0ea90ca918170b882390b2e3d770aefcf0 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 6 Jun 2019 20:00:44 +0200 Subject: [PATCH 5/5] Rename FunctionBetaReduction to AsFunction --- docs/docs/reference/metaprogramming/macros.md | 10 +++++----- library/src-3.x/scala/quoted/Expr.scala | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index 681401890797..1144622c1ca7 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -135,24 +135,24 @@ expressiveness. ### From `Expr`s to Functions and Back -The `Expr` companion object contains an implicit `FunctionBetaReduction` conversion that turns a tree +The `Expr` companion object contains an implicit `AsFunction` conversion that turns a tree describing a function into a function mapping trees to trees. ```scala object Expr { ... - implicit class FunctionBetaReduction[...](...) { ... } + implicit class AsFunction[...](...) { ... } } ``` This decorator gives `Expr` the `apply` operation of an applicative functor, where `Expr`s over function types can be applied to `Expr` arguments. The definition -of `FunctionBetaReduction(f).apply(x)` is assumed to be functionally the same as +of `AsFunction(f).apply(x)` is assumed to be functionally the same as `'{($f)($x)}`, however it should optimize this call by returning the result of beta-reducing `f(x)` if `f` is a known lambda expression. -The `FunctionBetaReduction` decorator distributes applications of `Expr` over function +The `AsFunction` decorator distributes applications of `Expr` over function arrows: ```scala - FunctionBetaReduction(f).apply: Expr[S => T] => (Expr[S] => Expr[T]) + AsFunction(_).apply: Expr[S => T] => (Expr[S] => Expr[T]) ``` Its dual, let’s call it `reflect`, can be defined as follows: ```scala diff --git a/library/src-3.x/scala/quoted/Expr.scala b/library/src-3.x/scala/quoted/Expr.scala index e79f96212f25..2300346c8b7b 100644 --- a/library/src-3.x/scala/quoted/Expr.scala +++ b/library/src-3.x/scala/quoted/Expr.scala @@ -24,13 +24,13 @@ package quoted { /** Converts a tuple `(T1, ..., Tn)` to `(Expr[T1], ..., Expr[Tn])` */ type TupleOfExpr[Tup <: Tuple] = Tuple.Map[Tup, Expr] - implicit class FunctionBetaReduction[F, Args <: Tuple, R](f: Expr[F]) given (tf: TupledFunction[F, Args => R]) { + implicit class AsFunction[F, Args <: Tuple, R](f: Expr[F]) given (tf: TupledFunction[F, Args => R]) { /** Beta-reduces the function appication. Generates the an expression only containing the body of the function */ def apply[G] given (tg: TupledFunction[G, TupleOfExpr[Args] => Expr[R]]): G = tg.untupled(args => new FunctionAppliedTo[R](f, args.toArray.map(_.asInstanceOf[Expr[_]]))) } - implicit class ContextualFunctionBetaReduction[F, Args <: Tuple, R](f: Expr[F]) given (tf: TupledFunction[F, given Args => R]) { + implicit class AsContextualFunction[F, Args <: Tuple, R](f: Expr[F]) given (tf: TupledFunction[F, given Args => R]) { /** Beta-reduces the function appication. Generates the an expression only containing the body of the function */ def apply[G] given (tg: TupledFunction[G, TupleOfExpr[Args] => Expr[R]]): G = tg.untupled(args => new FunctionAppliedTo[R](f, args.toArray.map(_.asInstanceOf[Expr[_]])))