2010-01-14 17 views
12

Sono un po 'instabile sulle regole in merito a quando è necessario un _ dopo un metodo per utilizzarlo come funzione. Ad esempio, perché c'è una differenza tra Foo e :: in ::?Perché e quando devo seguire un nome di metodo con _?

def square(n: Int) = n * n 
object Foo { def ::(f: Int => Int) = f(42) } 

// ... 

scala> Foo.::(square) 
res2: Int = 1764 

scala> Nil.::(square) 
<console>:6: error: missing arguments for method square in object $iw; 
follow this method with `_' if you want to treat it as a partially applied function 
    Nil.::(square) 
     ^
scala> Nil.::(square _) 
res3: List[(Int) => Int] = List(<function1>) 

risposta

15

Quando si omette tutti i parametri in un'espressione di funzione parzialmente applicata, allora è necessario seguire con _meno compilatore richiede un tipo di funzione nel luogo in cui si utilizza.

Quando si chiama il metodo :: su Foo, il compilatore prevede un tipo Int => Int per il parametro. Quindi puoi tranquillamente omettere il carattere di sottolineatura dopo square in quella posizione.

Tuttavia, il metodo :: su Nil può avere un parametro di qualsiasi tipo. Quindi, piuttosto che assumere che intendevi applicare parzialmente la funzione, si lamenta a meno che non lo rendi assolutamente esplicito aggiungendo _.

Quindi queste sono le regole ... Non posso davvero illuminarti su perché quelle sono le regole; forse qualcun altro che ha una migliore conoscenza del compilatore, del sistema di tipi e del design del linguaggio sarà in grado di dirti perché. Ma presumo che senza queste regole, ci sarebbe il rischio di un'ambiguità accidentale in molti luoghi.

+2

Grazie. Ho appena trovato una parte della Scala Language Spec che dà qualche giustificazione per il "perché", nelle note di modifica di Scala 2.0: "Le regole per le conversioni implicite dei metodi alle funzioni (§6.25) sono state rafforzate. In precedenza, un metodo parametrizzato utilizzato dato che un valore è sempre stato convertito implicitamente in una funzione, il che potrebbe portare a risultati imprevisti quando gli argomenti del metodo sono stati dimenticati. Prendiamo ad esempio la seguente istruzione: show (x.toString) ... " –

Problemi correlati