Domanda

Durante la creazione di una mappa di stringa per funzioni parziali ho incontrato un comportamento imprevisto. Quando creo una funzione parziale come un elemento della mappa funziona benissimo. Quando ho assegnare ad una val invoca invece. Cercando di invocare il controllo genera un errore. È questo previsto? Sto facendo qualcosa di stupido? Commentare la check() per vedere l'invocazione. Sto usando Scala 2.7.7

def PartialFunctionProblem() = {
    def dream()() = {
        println("~Dream~");
        new Exception().printStackTrace()
    }
    val map = scala.collection.mutable.HashMap[String,()=>Unit]()
    map("dream") = dream()      // partial function
    map("dream")()              // invokes as expected
    val check = dream()         // unexpected invocation
    check()                     // error: check of type Unit does not take parameters 
}
È stato utile?

Soluzione

Per comodità, Scala consente di omettere svuota parentesi quando si chiama un metodo, ma è abbastanza intelligente per capire che tipo previsto nel primo caso è ()=>Unit, in modo da non rimuovere tutte le parentesi per voi; invece, converte il metodo in una funzione per voi.

Nel caso val check, tuttavia, sembra proprio come un risultato della funzione chiamata sempre assegnata a una variabile. In realtà, tutti e tre di questi fanno la stessa identica cosa:

val check = dream
val check = dream()
val check = dream()()

Se si desidera attivare il metodo in una funzione, si posiziona _ dopo che il metodo al posto della lista degli argomenti (s) . Così,

val check = dream() _

farà quello che vuoi.

Altri suggerimenti

Bene, il problema è che hai sbagliato tutto. : -)

Ecco alcuni degli errori concettuali:

def dream()() = {
    println("~Dream~");
    new Exception().printStackTrace()
}

Questa non è una funzione parziale. Questo è un metodo curry con due liste di parametri vuoti che restituisce Unit.

val map = scala.collection.mutable.HashMap[String,()=>Unit]()

Il tipo di valori di questo mappa non è funzione parziale, ma funzione. Specificamente, Function0[Unit]. Una funzione parziale avrebbe tipo PartialFunction[T, R].

map("dream") = dream()      // partial function

Cosa accade è che Scala convertiti il metodo parzialmente applicato in una funzione. Questo non è un compito semplice. Scala esegue la conversione perché il tipo inferencer può indovinare il tipo corretto.

val check = dream()         // unexpected invocation

Tipo Qui non c'è nessun dovrebbe aiutare il tipo inferencer. Tuttavia, elenchi di parametri vuoti possono essere omessi, quindi questo è solo una chiamata di metodo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top