Skip to content

Commit

Permalink
Remove TupledFunction tuppled, apply, andThen and compose from stdlib
Browse files Browse the repository at this point in the history
All these operations can and probably should be implemented in a library.
  • Loading branch information
nicolasstucki committed May 28, 2019
1 parent 5f07a17 commit f6eb444
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 68 deletions.
11 changes: 0 additions & 11 deletions library/src-3.x/dotty/DottyPredef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)

}
53 changes: 0 additions & 53 deletions library/src-3.x/scala/TupledFunction.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

}
14 changes: 13 additions & 1 deletion tests/run/tupled-function-andThen.scala
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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))
}

}
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
object Test {
def main(args: Array[String]): Unit = {
import TupledFunction._

val f0 = () => 0
val t0 = ()
Expand Down Expand Up @@ -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)
}
16 changes: 14 additions & 2 deletions tests/run/tupled-function-compose.scala
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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))
}

}
11 changes: 11 additions & 0 deletions tests/run/tupled-function-tupled.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

0 comments on commit f6eb444

Please sign in to comment.