Pour autant que je sache, il n'existe que deux types de fonctions, destructives et constructives.
Alors que la fonction constructive, comme son nom l'indique, construit quelque chose, la fonction destructive détruit quelque chose, mais pas de la manière dont vous pouvez le penser maintenant.
Par exemple, la fonction
Function<Integer,Integer> f = (x,y) -> x + y
est un constructive un. Comme vous avez besoin de construire quelque chose. Dans l'exemple vous avez construit le tuple (x,y) . Les fonctions constructives ont le problème, de ne pas pouvoir gérer des arguments infinis. Mais le pire, c'est que vous ne pouvez pas simplement laisser un argument ouvert. On ne peut pas juste dire "bien, laissez x := 1" et essayer tous les y que vous pourriez vouloir essayer. Vous devez construire à chaque fois le tuple complet avec x := 1
. Donc si vous voulez voir ce que les fonctions retournent pour y := 1, y := 2, y := 3
vous devez écrire f(1,1) , f(1,2) , f(1,3)
.
En Java 8, les fonctions constructives doivent être gérées (la plupart du temps) en utilisant des références de méthode, car il n'y a pas beaucoup d'avantages à utiliser une fonction lambda constructive. Elles sont un peu comme les méthodes statiques. Vous pouvez les utiliser, mais elles n'ont pas d'état réel.
L'autre type est le type destructeur, il prend quelque chose et le démonte autant que nécessaire. Par exemple, le destructeur fonction
Function<Integer, Function<Integer, Integer>> g = x -> (y -> x + y)
fait la même chose que la fonction f
ce qui était constructif. Les avantages d'une fonction destructive sont, vous pouvez gérer maintenant des arguments infinis, ce qui est particulièrement pratique pour les flux, et vous pouvez simplement laisser des arguments ouverts. Ainsi, si vous voulez à nouveau voir quel serait le résultat si x := 1
y y := 1 , y := 2 , y := 3
vous pouvez dire h = g(1)
y h(1)
est le résultat pour y := 1
, h(2)
para y := 2
y h(3)
para y := 3
.
Vous avez donc ici un état fixe ! C'est assez dynamique et c'est la plupart du temps ce que nous attendons d'un lambda.
Les modèles tels que Factory sont beaucoup plus simples si vous pouvez simplement intégrer une fonction qui fait le travail à votre place.
Les destructeurs se combinent facilement entre eux. Si le type est bon, vous pouvez les composer comme vous le souhaitez. En utilisant cela, vous pouvez facilement définir des morphismes qui rendent les tests (avec des valeurs immuables) beaucoup plus faciles !
Vous pouvez également le faire avec une composition constructive, mais la composition destructive ressemble davantage à une liste ou à un décorateur, tandis que la composition constructive ressemble beaucoup à un arbre. Et des choses comme le retour en arrière avec des fonctions constructives ne sont tout simplement pas agréables. Vous pouvez simplement sauvegarder les fonctions partielles d'une fonction destructive (programmation dynamique), et lors du "retour en arrière", utiliser l'ancienne fonction destructive. Cela rend le code beaucoup plus petit et plus lisible. Avec les fonctions constructives, vous devez plus ou moins vous souvenir de tous les arguments, ce qui peut être beaucoup.
Alors pourquoi faut-il BiFunction
devrait être une question plus importante que la raison pour laquelle il n'y a pas de TriFunction
?
Tout d'abord, la plupart du temps, vous n'avez que quelques valeurs (moins de 3) et vous n'avez besoin que d'un résultat. Une fonction destructive normale ne serait donc pas nécessaire, une fonction constructive ferait l'affaire. Et il y a des choses comme les monades qui ont vraiment besoin d'une fonction constructive. Mais en dehors de cela, il n'y a pas vraiment beaucoup de bonnes raisons pour lesquelles il y a une fonction constructive. BiFunction
du tout. Ce qui ne veut pas dire qu'il faut le supprimer ! Je me battrai pour mes Monads jusqu'à ma mort !
Donc, si vous avez beaucoup d'arguments, que vous ne pouvez pas combiner dans une classe conteneur logique, et si vous avez besoin de l'option fonction soit constructive, utilisez une référence de méthode. Sinon, essayez d'utiliser la nouvelle capacité acquise des fonctions destructives, vous pourriez vous retrouver à faire beaucoup de choses avec beaucoup moins de lignes de code.