Ich habe mich gefragt, ob es eine Möglichkeit gibt, dies in Java zu erreichen. Ich denke, es ist nicht möglich ohne native Unterstützung für Schließungen.
88
Ich habe mich gefragt, ob es eine Möglichkeit gibt, dies in Java zu erreichen. Ich denke, es ist nicht möglich ohne native Unterstützung für Schließungen.
Antworten:
Java 8 (veröffentlicht am 18. März 2014) unterstützt das Currying. Der in der Antwort von fehlenden Faktor angegebene Java-Beispielcode kann wie folgt umgeschrieben werden:
... was ganz nett ist. Persönlich sehe ich mit Java 8 wenig Grund, eine alternative JVM-Sprache wie Scala oder Clojure zu verwenden. Sie bieten natürlich andere Sprachfunktionen, aber das reicht nicht aus, um die Übergangskosten und die schwächere Unterstützung für IDE / Tools / Bibliotheken, IMO, zu rechtfertigen.
quelle
(def adder5 (partial + 5)) (prn (adder5 4)) (prn adder5 6)
Currying und teilweise Anwendung sind in Java absolut möglich, aber die erforderliche Codemenge wird Sie wahrscheinlich ausschalten.
Einige Codes zur Demonstration von Currying und Teilanwendung in Java:
FWIW hier ist das Haskell-Äquivalent des obigen Java-Codes:
quelle
Es gibt viele Optionen für das Currying mit Java 8. Die Funktionstypen Javaslang und jOOλ bieten beide Currying out of the box an (ich denke, dies war ein Versehen im JDK), und das Modul Cyclops Functions verfügt über eine Reihe statischer Methoden zum Currying von JDK-Funktionen und Methodenreferenzen. Z.B
"Currying" ist auch für Verbraucher erhältlich. Um beispielsweise eine Methode mit 3 Parametern zurückzugeben, und 2 der bereits angewendeten, machen wir etwas Ähnliches
Javadoc
quelle
currying
imCurry.curryn
Quellcode.EDIT : Ab 2014 und Java 8 ist funktionale Programmierung in Java nicht nur möglich, sondern auch nicht hässlich (ich wage es schön zu sagen). Siehe zum Beispiel Rogerios Antwort .
Alte Antwort:
Java ist nicht die beste Wahl, wenn Sie funktionale Programmiertechniken verwenden möchten. Wie der fehlende Faktor geschrieben hat, müssen Sie ziemlich viel Code schreiben, um das zu erreichen, was Sie wollen.
Auf der anderen Seite sind Sie in JVM nicht auf Java beschränkt - Sie können Scala oder Clojure verwenden, die funktionale Sprachen sind (Scala ist in der Tat sowohl funktional als auch OO).
quelle
Beim Currying muss eine Funktion zurückgegeben werden . Dies ist mit Java nicht möglich (keine Funktionszeiger), aber wir können einen Typ definieren und zurückgeben, der eine Funktionsmethode enthält:
Lassen Sie uns nun eine einfache Unterteilung vornehmen . Wir brauchen einen Teiler :
und eine DivideFunction :
Jetzt können wir eine Curry-Division machen:
quelle
Nun, Scala , Clojure oder Haskell (oder jede andere funktionale Programmiersprache ...) sind definitiv DIE Sprachen , die zum Curryen und für andere funktionale Tricks verwendet werden.
Trotzdem ist es sicherlich möglich, mit Java zu curry, ohne die Super-Mengen an Boilerplate, die man erwarten könnte (nun, es tut sehr weh, explizit über die Typen sprechen zu müssen - schauen Sie sich einfach das
curried
Beispiel an ;-)).Die Tests unten beide präsentieren, currying ein
Function3
inFunction1 => Function1 => Function1
:sowie teilweise Anwendung , obwohl es in diesem Beispiel nicht wirklich typsicher ist:
Dies stammt aus einem Proof Of Concept, den ich morgen in einer Stunde vor JavaOne zum Spaß implementiert habe, "weil mir langweilig war" ;-) Der Code ist hier verfügbar: https://github.com/ktoso/jcurry
Die allgemeine Idee könnte relativ einfach auf FunctionN => FunctionM erweitert werden, obwohl "echte Typensicherheit" ein Problem für das partia-Anwendungsbeispiel bleibt und das Currying-Beispiel eine Menge Boilerplaty-Code in jcurry erfordern würde , aber es ist machbar.
Alles in allem ist es machbar, aber in Scala ist es out of the box ;-)
quelle
Mit Java 7 MethodHandles kann man Currying emulieren: http://www.tutorials.de/threads/java-7-currying-mit-methodhandles.392397/
quelle
Ja, sehen Sie sich das Codebeispiel an:
Dies ist ein einfaches Beispiel, bei dem curriedAdd eine Curry-Funktion ist, die eine andere Funktion zurückgibt, und dies kann zur teilweisen Anwendung von Parametern verwendet werden, die in curried gespeichert sind, was eine Funktion für sich ist. Dies wird jetzt später vollständig angewendet, wenn wir es auf dem Bildschirm drucken.
Darüber hinaus können Sie später sehen, wie Sie es in einer Art JS-Stil als verwenden können
quelle
Noch eine Sicht auf die Java 8-Möglichkeiten:
Sie können auch Dienstprogrammmethoden wie diese definieren:
Was Ihnen eine wohl besser lesbare Syntax gibt:
quelle
Das Currying einer Methode ist in Java immer möglich, wird jedoch nicht standardmäßig unterstützt. Der Versuch, dies zu erreichen, ist kompliziert und macht den Code ziemlich unlesbar. Java ist hierfür nicht die geeignete Sprache.
quelle
Eine andere Wahl ist hier für Java 6+
dann könnten Sie auf diese Weise Currying erreichen
quelle
Während Sie Currying in Java ausführen können, ist es hässlich (weil es nicht unterstützt wird). In Java ist es einfacher und schneller, einfache Schleifen und einfache Ausdrücke zu verwenden. Wenn Sie ein Beispiel für die Verwendung von Curry veröffentlichen, können wir Alternativen vorschlagen, die dasselbe tun.
quelle
2 * ?
In Java würden Sie dies mit einer Schleife tun.Dies ist eine Bibliothek für Currying und Teilanwendung in Java:
https://github.com/Ahmed-Adel-Ismail/J-Curry
Es unterstützt auch die Destrukturierung von Tupeln und Map.Entry in Methodenparameter, z. B. das Übergeben eines Map.Entry an eine Methode, die zwei Parameter akzeptiert, sodass Entry.getKey () zum ersten Parameter und Entry.getValue () wechselt. wird für den zweiten Parameter gehen
Weitere Details in der README-Datei
quelle
Der Vorteil der Verwendung von Currying in Java 8 besteht darin, dass Sie Funktionen höherer Ordnung definieren und dann eine Funktion erster Ordnung und Funktionsargumente auf verkettete, elegante Weise übergeben können.
Hier ist ein Beispiel für Calculus, die Ableitungsfunktion.
quelle
Ja, ich stimme @ Jérôme zu, Curring in Java 8 wird nicht wie in Scala oder anderen funktionalen Programmiersprachen standardmäßig unterstützt.
quelle