eta-expansionとは、メソッドを関数に変換する処理です。 たとえば、
def add(x: Int, y: Int): Int = x + y val addFunc = add _
で、add _
によって、eta-expansionが行われ、メソッドadd
が関数に変換されます。このeta-expansion、メソッドがオーバーロードされていると一見正しく行うことができないように見えます。
object O { def add(x: Double, y: Int): Double = x + y def add(x: Int, y: Double): Double = x + y } O.add _ <console>:13: error: ambiguous reference to overloaded definition, both method add in object O of type (x: Int, y: Double)Double and method add in object O of type (x: Double, y: Int)Double match expected type ? O.add _ ^
これに対して、次のようにしてやればeta-expansionを行うことができます。
object O { def add(x: Double, y: Int): Double = x + y def add(x: Int, y: Double): Double = x + y } O.add _:((Double, Int) => Double)
要はどのような型の関数に変換するか明示してやればいいわけです。eta-expansionは変換先の型を意識せずにできるのがメリットなのでこうしなければいけない時点でメリットが半減シますが、一応回避策はある、ということで。