2015-05-16 16 views
6

Die folgende:Warum kompiliert diese Teilanwendung nicht?

object a1 extends Function1[Int, Int] { 
    def apply(x: Int): Int = { 
    add(x, 3) 
    } 
} 

Aber wenn ich das tue:

object add extends Function2[Int, Int, Int] { 
    def apply(a: Int, b: Int) = a + b 
} 

während

val a1 = add(_: Int, 3) 
an wird

umgewandelt:

val add = (a: Int, b: Int) => a + b 

umgewandelt wird

scala> val a2 = add _ 
a2:() => (Int, Int) => Int = <function0> 

Und dann a2 nennen, wirft er einen Fehler:

scala> a2(1, 2) 
<console>:11: error: too many arguments for method apply:()(Int, Int) => Int in trait Function0 
       a2(1, 2) 
       ^

Warum ist das? Warum funktioniert das Folgende?

a2()(1, 2) 

Antwort

9

add ist bereits ein Function2[Int, Int, Int]. Wenn Sie möchten, dass a2 denselben Typ hat, dann genügt eine einfache Zuweisung.

scala> val a2 = add 
a2: (Int, Int) => Int = <function2> 

scala> a2(1, 2) 
res3: Int = 3 

Was Sie denken, ist Eta-Erweiterung einer Methode in eine Funktion. Hätten wir:

def add(a: Int, b: Int): Int = a + b 

Dann, würden wir add _ verwenden, um die eta-Expansion zu bekommen auf einen Wert zuzuweisen.

scala> def a2 = add _ 
a2: (Int, Int) => Int 

scala> a2(1, 2) 
res4: Int = 3 

Aber add ist bereits eine Funktion, so dass der Unterstrich hat eine andere Bedeutung. add ist jetzt ein Wert und kein Methode. Da add ein Wert ist, ist es wie eine parameterlose Methode, die eine Function2[Int, Int, Int] zurückgibt. Und wenn wir versuchen, die Eta-Erweiterung davon zu bekommen, erhalten wir () => Function2[Int, Int, Int].

Betrachten Sie ein einfacheres Beispiel, wo wir eine einfache val a = 1 haben. a ist im Wesentlichen das gleiche wie eine parameterlose Methode, die 1 (def a = 1) zurückgibt. Wenn ich versuche, die Eta-Erweiterung zu erhalten, bekomme ich () => Int.

scala> val a = 1 
a: Int = 1 

scala> val a2 = a _ 
a2:() => Int = <function0> 
Verwandte Themen