Frage

Während eine Karte von String zu Teilfunktionen zu schaffen ich in einem unerwartetes Verhalten lief. Wenn ich eine Teilfunktion als Kartenelement erstellen funktioniert es gut. Wenn ich zu einem val zuweisen ruft sie stattdessen. Der Versuch, den Scheck aufzurufen erzeugt einen Fehler. Ist das zu erwarten? Mache ich etwas dumm? Kommentieren Sie die check() den Aufruf zu sehen. Ich bin mit 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 
}
War es hilfreich?

Lösung

Der Einfachheit halber Scala können Sie Pars beim Aufruf einer Methode leeren auslassen, aber es ist klug genug, um zu sehen, dass die erwartete Art im ersten Fall ist ()=>Unit, so dass es nicht alle die Pars für Sie nicht entfernen; sondern es wandelt das Verfahren in eine Funktion für Sie.

Im val check Fall aber es sieht aus wie ein Funktionsaufruf Ergebnis einer Variablen zugewiesen bekommen. In der Tat, alle drei von ihnen tun genau dasselbe:

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

Wenn Sie die Methode in eine Funktion aktivieren möchten, Sie legen _ nach der Methode anstelle der Argumentliste (n) . So

val check = dream() _

wird tun, was Sie wollen.

Andere Tipps

Nun, das Problem ist, dass Sie es alle falsch. : -)

Hier sind einige konzeptionelle Fehler:

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

Dies ist nicht eine Teilfunktion. Dies ist eine curried Methode mit zwei leeren Parameterlisten, die Unit zurück.

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

Der Typ der Werte in dieser Karte ist nicht Teil-Funktion, sondern Funktion. Insbesondere Function0[Unit]. Eine Teilfunktion würde Typ PartialFunction[T, R] haben.

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

Was hier passiert, ist, dass Scala Konvertiten die teilweise angewandte Methode in eine Funktion. Dies ist keine einfache Aufgabe. Scala führt die Konvertierung, da der Typ Rückschließer den richtigen Typ erraten kann.

val check = dream()         // unexpected invocation

Hier gibt es keinen erwarteten Typ den Typ Rückschließer zu helfen. Allerdings können leere Parameterlisten weggelassen werden, so dass dies nur ein Methodenaufruf ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top