次のように、カリー化された関数を受け取り、引数を反転する汎用関数を記述できるかどうか疑問に思っていました。
def foo(a: String)(b: Boolean)(c: Int): String
val bar = invert(foo _)
foo("baz")(false)(12) must be equalTo(bar(12)(false)("baz"))
以下は、対処したい特定のケースに暗黙的なインバーターを追加する限り機能します。しかし、私はより一般的なケース、つまり、任意の数のカリー化された引数を扱うケースにもっと興味があります。
trait Inverter[V, W] {
def invert(v: V): W
}
implicit def function2Inverter[X, Y, Z] =
new Inverter[(X, Y) => Z, (Y, X) => Z] {
def invert(v: (X, Y) => Z) = {
def inverted(y: Y, x: X) = v(x, y)
inverted _
}
}
implicit def curried2Inverter[X, Y, Z] =
new Inverter[X => Y => Z, Y => X => Z] {
def invert(v: (X) => (Y) => Z) = {
def inverted(y: Y)(x: X) = v(x)(y)
inverted _
}
}
def invert[V, W](v: V)(implicit inverter: Inverter[V, W]): W =
inverter.invert(v)
ああ、Scala 2.9 でも動作するソリューションが欲しいです。