Les méthodes chaînées qui nécessitent un seul paramètre par méthode sont-elles équivalentes au curry?

15

J'ai joué avec Ruby ces derniers temps et je me suis demandé si dans les langages orientés objet purs (et même ceux qui ne sont pas purs), créer des méthodes qui ne prennent qu'un seul paramètre et qui sont ensuite enchaînées équivaut à curry dans des langages avec une fonction style? Sinon, pourquoi pas? J'apprécierais une réponse détaillée, voire rigoureuse sur le sujet.

Ingénieur du monde
la source

Réponses:

14

Le chaînage de méthodes dans les langages orientés objet est un peu différent du currying. Par définition , le résultat du curry est une forme plus restreinte de la fonction d' origine . Par convention , le résultat du chaînage de procédé est une forme modifiée de l'original (généralement non-fonction) objet . Le chaînage de méthodes peut être utilisé avec des méthodes non apparentées sur la même classe, tandis que le currying implique le retour d'une fonction où un ou plusieurs paramètres de la fonction d'origine sont fixes (prédéterminés).

En Java, le chaînage de méthodes est comme:

String myString = new StringBuilder("Hi ").append(firstName)
                                          .append(" ")
                                          .append(lastName)
                                          .append("!")
                                          .toString();

Ainsi, chacun de ces appels de méthode .append () renvoie un pointeur sur l'objet StringBuilder anonyme. Cet objet est complet après chaque .append (), et ce n'est pas une fonction.

En revanche, à Scala, une application partielle ou un curry est comme:

def simple(x:Int, y:Int, z:Int) = x * (y + z)
val simpler = simple(2, _:Int, _:Int)
simpler(3, 4) => 14

(Échantillon extrait du blog de Daniel Yankowsky )

simpler()dans cet exemple est une fonction wrapper pour simple(). simpler()est toujours une fonction qui prend plus de paramètres avant de pouvoir évaluer autre chose qu'une version plus limitée d'elle-même.

EDIT: En lisant ceci un jour plus tard, je pense que "wrapper-function" est la clé. Il est préférable de simuler le currying ou une application partielle en Java avec des méthodes wrapper.

public interface Simpler {
    public int apply(int y, int z);
}

public class Simple {
    public int apply(int x, int y, int z) { return x * (y + z); }

    public Simpler partiallyApply(final int x) {
        final simple = this;
        return new Simpler() {
            @Override
            public int apply(int y, int z) {
                // x is the final int parameter to partiallyApply()
                simple.apply(x, y, z);
            }
        }
    }
}

: END-EDIT

Le chaînage de méthodes peut être similaire à une application partielle ou au curry, mais il ne peut être équivalent qu'à des méthodes qui renvoient d'autres méthodes (recherchez des foncteurs), puis les méthodes doivent être configurées avec des types de retour qui modélisent de manière significative le curry ou l'application partielle.

Le chaînage de méthodes est plus souvent utilisé pour implémenter quelque chose comme une évaluation paresseuse, comme cela se fait avec le modèle de conception "Builder" et les nouvelles interfaces de la bibliothèque de collections dans Java 8 .

J'espère que ça aide.

GlenPeterson
la source
+1: Je le savais, mais je ne pense pas que j'aurais pu l'exprimer aussi près que vous.
Peter Rowell
Bien expliqué, voici une coche verte et une note positive pour votre problème.
World Engineer
Question sur le très bel exemple de StringBuilder - sans l' toString()appel, ne reproduisons-nous pas effectivement l'intention de curryer dans notre appel? J'essaie juste de comprendre le concept de curry en OO.
Sridhar Sarnobat
1
@ Sridhar-Sarnobat une fonction curry renvoie une autre fonction avec moins de paramètres. Les paramètres éliminés sont transformés en constantes internes dans la fonction renvoyée. Certains objets sont traités comme des fonctions dans Java 8, ce qui peut prêter à confusion, mais StringBuilder n'en fait pas partie. Hmm, dans StringBuilder, la append(charSeq)fonction est une forme curry de la insert(destOffset, charSeq)fonction où destOffsetest toujours la longueur du StringBuilder.
GlenPeterson