Wann benötigt der Scala-Compiler wirklich die Typinformation von Parametern anonymer Funktionen?
Zum Beispiel mit dieser Funktion:
%Vor%dann kann ich es nicht so benutzen:
%Vor%und ich muss
angeben %Vor%was ziemlich hässlich ist. Warum funktioniert mein Beispiel nicht, während Methoden wie map, filter, foldLeft usw. für die Collection-Klassen diesen expliziten Typ nicht zu benötigen scheinen?
Der Trick, Inferenz zu schreiben, besteht darin, es als einen Prozess der iterativen Verfeinerung zu betrachten. Jeder Parameterblock kann verwendet werden, um einige der Typparameter abzuleiten, die dann in nachfolgenden Blöcken verwendet werden können. Nimm die folgende Definition:
%Vor%wird wie folgt aufgerufen:
%Vor% Wie wird das abgeleitet? Zuerst beginnen wir mit dem Block (2)
, von dem bekannt ist, dass er den Typ Int
hat. Ersetzen wir dies durch den Parameter T
, erhalten wir:
Der nächste Parameterblock ist (_*10)
, wo wir jetzt den Typ des Platzhalters _
als Int
... kennen und ein Int
mit einem Int
multipliziert mit einem anderen Int
multiplizieren. Dies gilt auch für den zurückgegebenen Typ, wenn ein Überlauf auftritt. am äußersten Ende kann es eine Ausnahme auslösen, aber Ausnahmen haben den Typ Nothing
, was eine Unterklasse von allem anderen im Typsystem ist, also können wir immer noch sagen Nothing
ist-ein Int
und der abgeleitete Typ Int
ist immer noch gültig.
Wenn A
abgeleitet wird, wird die Methode zu
Nur B
lassen, was aus ("xxx"+_)
abgeleitet werden kann. Da String + Int
ein String
ist, lautet die Methode nun:
Da der Rückgabetyp der Methode direkt von fn2
kommt, kann dies auch explizit der Vollständigkeit halber gezeigt werden:
Da haben Sie es, alle Arten sicher gelöst, und die Methode hat sich als statisch bewährt.
In Ihrem Fall müssen Sie den Typ T
ableiten, bevor Sie R
vom Typ T=>R
ableiten können. Um dies zu tun, müssen Sie die Parameter in zwei verschiedene Blöcke aufteilen und die Methode in einer Curry-Form schreiben:
Diese Frage wurde auch hier beantwortet:
Funktionen für alle zutreffenden Typen übergeben
Sie erwarten, ... dass der Scala-Compiler beide Parameter doppelt berücksichtigt, um die richtigen Typen zu ermitteln. Scala macht das jedoch nicht - es verwendet nur Informationen von einer Parameterliste zur nächsten, aber nicht von einem Parameter zum nächsten. Das bedeutet, dass die Parameter f und a [WS: Ziel und f in diesem Fall] unabhängig voneinander analysiert werden, ohne den Vorteil zu haben, zu wissen, was der andere ist.
Beachten Sie, dass mit einer Curry-Version funktioniert:
%Vor%Tags und Links scala type-inference anonymous-function