Ich habe bereits mehrere Java 8-Tutorials gelesen.
Im Moment bin ich auf folgendes Thema gestoßen: Unterstützt Java Currying?
Hier sehe ich folgenden Code:
IntFunction<IntUnaryOperator> curriedAdd = a -> b -> a + b;
System.out.println(curriedAdd.apply(1).applyAsInt(12));
Ich verstehe, dass dieses Beispiel 2 Elemente summiert, aber ich kann die Konstruktion nicht verstehen:
a -> b -> a + b;
Gemäß dem linken Teil des Ausdrucks sollte diese Zeile die folgende Funktion implementieren:
R apply(int value);
Vorher habe ich nur Lambdas mit einem Pfeil getroffen.
Antworten:
Wenn Sie dies als Nicht-Kurzschrift-Lambda-Syntax oder als anonyme Java-Klassensyntax vor Lambda ausdrücken, ist klarer, was passiert ...
Die ursprüngliche Frage. Warum sind zwei Pfeile? Einfach, es werden zwei Funktionen definiert ... Die erste Funktion ist eine funktionsdefinierende Funktion, die zweite ist das Ergebnis dieser Funktion, die zufällig auch eine Funktion ist. Für jeden muss ein
->
Operator definiert werden.Nicht Kurzschrift
Pre-Lambda vor Java 8
quelle
final int value
pre-lambda
An
IntFunction<R>
ist eine Funktionint -> R
. AnIntUnaryOperator
ist eine Funktionint -> int
.Somit
IntFunction<IntUnaryOperator>
ist an eine Funktion, die einenint
as-Parameter verwendet und eine Funktion zurückgibt, die einenint
as-Parameter verwendet und einen zurückgibtint
.Vielleicht ist es klarer, wenn Sie anonyme Klassen verwenden, um das Lambda zu "zerlegen":
quelle
Das Hinzufügen von Klammern kann dies deutlicher machen:
Oder wahrscheinlich kann eine Zwischenvariable helfen:
quelle
Schreiben wir diesen Lambda-Ausdruck in Klammern um, um es klarer zu machen:
Wir deklarieren also eine Funktion mit a,
int
die a zurückgibtFunction
. Insbesondere nimmt die zurückgegebene Funktion einint
und gibt einint
(die Summe der beiden Elemente) zurück: Dies kann als dargestellt werdenIntUnaryOperator
.Daher
curriedAdd
ist eine Funktion eineint
und nimmt eine zurückIntUnaryOperator
, so dass sie als dargestellt werden kannIntFunction<IntUnaryOperator>
.quelle
Es sind zwei Lambda-Ausdrücke.
quelle
Wenn Sie es betrachten
IntFunction
, könnte es klarer werden:IntFunction<R>
ist aFunctionalInterface
. Es stellt eine Funktion dar, dieint
einen Wert vom Typ annimmt und zurückgibtR
.In diesem Fall ist der Rückgabetyp
R
auch aFunctionalInterface
, nämlich anIntUnaryOperator
. Die erste (äußere) Funktion selbst gibt also eine Funktion zurück.In diesem Fall: Wenn auf ein angewendet
int
,curriedAdd
soll eine Funktion zurückgegeben werden, die wieder ein übernimmtint
(und wieder zurückgibtint
, weil dies derIntUnaryOperator
Fall ist).In der funktionalen Programmierung ist es üblich, den Typ einer Funktion als zu schreiben,
param -> return_value
und genau das sehen Sie hier. So ist die Art voncurriedAdd
istint -> int -> int
(oder ,int -> (int -> int)
wenn Sie so besser).Die Lambda-Syntax von Java 8 geht damit einher. Um eine solche Funktion zu definieren, schreiben Sie
Das ist dem tatsächlichen Lambda-Kalkül sehr ähnlich:
λb a + b
ist eine Funktion, die einen einzelnen Parameter verwendetb
und einen Wert (die Summe) zurückgibt.λa λb a + b
ist eine Funktion, die einen einzelnen Parameter akzeptiert und einea
andere Funktion eines einzelnen Parameters zurückgibt.λa λb a + b
kehrtλb a + b
mita
auf den Parameterwert gesetzt zurück.quelle