java-curry une fonction statique existante


Pour tirer pleinement parti de la composition des fonctions en Java, j'aimerais curry certaines fonctions statiques existantes que j'utilise couramment. Un candidat parfait pour currying est Apache Commons StringUtils .

Pour un exemple concret, imaginons que je voulais le curry StringUtils.remove(String str, String remove) méthode pour fournir une fonction appelée (dire) removeCommas.

Une implémentation possible est:

Function<String, String> removeCommas = s -> StringUtils.remove(s, ",");

Cependant ce n'est pas nourrissage. Je m'attendrais à pouvoir utiliser l'opérateur de référence de méthode (par exemple StringUtils::remove) pour y parvenir d'une manière plus fonctionnelle, mais je ne peux pas comprendre à quoi ressemblerait la syntaxe.

Pensées?

Author: Roy Truelove, 2017-03-16

3 answers

, Vous pouvez curry remove() comme ceci:

Function<String, Function<String, String>> remove = r -> s -> StringUtils.remove(s, r);
Function<String, String> removeCommas = remove.apply(",");

Si vous préférez la référence de méthode, vous pouvez créer une méthode d'aide générique pour curry n'importe quelle méthode à arité fixe:

static <T, U, R> Function<T, Function<U, R>> curry(BiFunction<T, U, R> function) {
    return a -> b -> function.apply(a, b);
}
// ...
Function<String, Function<String, String>> remove = curry(StringUtils::remove);

Notez que cet assistant suit l'ordre des paramètres, de sorte que la fonction ci-dessus capturerait la chaîne cible avant la chaîne de suppression. Il n'y a aucun moyen de réorganiser les paramètres dans une référence de méthode, vous devrez donc choisir une commande et vous y tenir.

 11
Author: shmosel, 2017-03-16 00:18:56

Java simple ne fournit pas de sucre syntaxique pour le currying. Toutefois, si vous êtes prêt à utiliser une bibliothèque tierce, vous pouvez utiliser Javaslang.

À côté des fonctions d'arité 0..8, il contient également des fonctions vérifiées (de même arité) qui permettent de lancer des exceptions. Ceux-ci fournissent les caractéristiques suivantes:

  • application partielle
  • fonctions au curry
  • fonctions tuplées
  • fonctions mémorisées (=mise en cache des résultats)
  • fonctions avec inversées paramètres
  • fonction de levage
  • ...

Dans notre cas concret ici, nous avons besoin de la liste des paramètres inversés avant de currying (ou d'appliquer partiellement) la méthode remove:

// currying
final Function1<String, Function1<String, String>> curried =
        Function2.of(StringUtils::remove).reversed().curried();

// partial application with reversed parameters
final Function1<String, String> removeCommas =
        Function2.of(StringUtils::remove).reversed().apply(",");

Function1 étend la fonction de Java, Function2 étend la BiFunction de Java pour des raisons d'interopérabilité.

Avertissement: Je suis le créateur de Javaslang

 3
Author: Daniel Dietrich, 2017-03-16 13:35:00

Les langages fonctionnels ont currying, car de nombreux langages fonctionnels sont limités aux fonctions avec un seul paramètre. Ceci est hérité du lambda calculus, qui est un langage/système formel dans la discipline de la logique mathématique.

Currying surmonte cette limitation, mais Java simple ne prend pas en charge currying.


il y a des Années, j'ai écrit une bibliothèque appelée jcurry, un exemple. Peut-être que vous le trouvez utile.

 0
Author: mike, 2017-03-16 00:19:25