主要的困难是你必须找出带有反向参数的函数的类型,如果没有宏,这是不可能的。
但由于 Scala 仅支持最多 22 个参数的函数,因此您可以为所有可能的参数的函数编写或生成 23 个实现。这是一个有 3 个参数的函数的示例:
def reverse[A, B, C, R](f: (A, B, C) => R): (C, B, A) => R =
(c, b, a) => f(a, b, c)
使用宏虽然可以以通用方式进行。最简单的解决方案可能是使用shapeless 库,它是在内部使用宏实现的。这是一个无形的示例实现:
import shapeless._
import shapeless.ops.function._
import shapeless.ops.hlist._
def reverseArgs[Func, Args <: HList, Res, RevArgs <: HList](f: Func)(implicit
// Convert the function to a function from a single HList argument.
fnToProduct: FnToProduct.Aux[Func, Args => Res],
// Compute the type of the reversed arguments HList.
r1: Reverse.Aux[Args, RevArgs],
// Get the function to reverse the reversed arguments back.
reverse: Reverse.Aux[RevArgs, Args],
// Convert the function of a single HList argument to a normal function
fnFromProduct: FnFromProduct[RevArgs => Res]
): fnFromProduct.Out = {
fnFromProduct((args: RevArgs) => fnToProduct(f)(reverse(args)))
}
这是它的工作原理:
scala> val f = reverseArgs((i: Int, d: Double, s: String) => (i + d).toString + s)
f: (String, Double, Int) => String = shapeless.ops.FnFromProductInstances$$anon$4$$Lambda$1191/2014583896@4d7933e7
scala> f("a", 1.5, 2)
res1: String = 3.5a