|
| 1 | +--- |
| 2 | +layout: doc-page |
| 3 | +title: "Tupled Function" |
| 4 | +--- |
| 5 | + |
| 6 | +Tupled Function |
| 7 | +---------------------- |
| 8 | + |
| 9 | +With functions bounded to arities up to 22 it was possible to generalize some operation on all function types using overloading. |
| 10 | +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. |
| 11 | +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. |
| 12 | + |
| 13 | +```scala |
| 14 | +/** Type class relating a `FunctionN[..., R]` with an equvalent tupled function `Function1[TupleN[...], R]` |
| 15 | + * |
| 16 | + * @tparam F a function type |
| 17 | + * @tparam G a tupled function type (function of arity 1 receiving a tuple as argument) |
| 18 | + */ |
| 19 | +@implicitNotFound("${F} cannot be tupled as ${G}") |
| 20 | +trait TupledFunction[F, G] { |
| 21 | + def apply(f: F): G |
| 22 | +} |
| 23 | +``` |
| 24 | + |
| 25 | + |
| 26 | +Examples |
| 27 | +-------- |
| 28 | +`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)) |
| 29 | + |
| 30 | +```scala |
| 31 | +/** Creates a tupled version of this function: instead of N arguments, |
| 32 | + * it accepts a single [[scala.Tuple]] argument. |
| 33 | + * |
| 34 | + * @tparam F the function type |
| 35 | + * @tparam Args the tuple type with the same types as the function arguments of F |
| 36 | + * @tparam R the return type of F |
| 37 | + */ |
| 38 | +def (f: F) tupled[F, Args <: Tuple, R] given (tupled: TupledFunction[F, Args => R]): Args => R = tupled(f) |
| 39 | +``` |
| 40 | + |
| 41 | +`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. |
| 42 | + |
| 43 | +```scala |
| 44 | +/** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied last |
| 45 | + * |
| 46 | + * @tparam F a function type |
| 47 | + * @tparam G a function type |
| 48 | + * @tparam FArgs the tuple type with the same types as the function arguments of F and return type of G |
| 49 | + * @tparam GArgs the tuple type with the same types as the function arguments of G |
| 50 | + * @tparam R the return type of F |
| 51 | + */ |
| 52 | +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 = { |
| 53 | + (x: GArgs) => tupledF(f)(tupledG(g)(x)) |
| 54 | +} |
| 55 | +``` |
0 commit comments