506 votes

Quelle est la différence entre corroyage et partielle de l’application

Je ne suis pas sûr de savoir exactement comment la parole à cette question.

J'ai appris ce que nourrissage était dans la première année de l'université, et ont été en utilisant le cas échéant depuis.

Cependant, j'ai assez souvent voir sur Internet les différentes plaintes que les autres peuples des exemples de nourrissage sont pas nourrissage, mais sont en fait juste une application partielle.

Je n'ai pas trouvé une bonne explication de ce que l'application partielle, ou en quoi elle diffère de nourrissage. Il semble y avoir une confusion générale, avec l'équivalent des exemples sont décrits comme étant nourrissage dans certains endroits, et l'application partielle dans d'autres.

Quelqu'un pourrait-il me donner une définition de ces deux termes, et les détails de la façon dont ils diffèrent-ils?

289voto

Mark Cidade Points 53945

Nourrissage est la conversion d'une seule fonction de n arguments en n de fonctions à un seul argument de chacun. Compte tenu de la fonction suivante:

function f(x,y,z) { z(x(y));}

Quand au curry, devient:

function f(x) { lambda(y) { lambda(z) { z(x(y)); } } }

Afin d'obtenir l'application intégrale de f(x,y,z), vous devez faire ceci:

f(x)(y)(z);

De nombreux langages fonctionnels vous permettent d'écrire des f x y z. Si vous ne vous appelez f x y ou f(x)(y) , puis vous obtenez partiellement appliqué en fonction de la valeur de retour est une fermeture d' lambda(z){z(x(y))} avec le passé-dans les valeurs de x et y f(x,y).

Une façon d'utiliser l'application partielle est de définir des fonctions que les applications partielles généralisé de fonctions, comme la fois:

function fold(combineFunction, accumalator, list) {/* ... */}
function sum     = curry(fold)(lambda(accum,e){e+accum}))(0);
function length  = curry(fold)(lambda(accum,_){1+accum})(empty-list);
function reverse = curry(fold)(lambda(accum,e){concat(e,accum)})(empty-list);

/* ... */
@list = [1, 2, 3, 4]
sum(list) //returns 10
@f = fold(lambda(accum,e){e+accum}) //f = lambda(accumaltor,list) {/*...*/}
f(0,list) //returns 10
@g = f(0) //same as sum
g(list)  //returns 10

186voto

Pacerier Points 15960

La meilleure façon de voir comment ils diffèrent, c'est de considérer un exemple réel. Supposons que nous avons une fonction Add qui prend 2 nombres en entrée et renvoie un nombre en sortie. E. g. Add(7, 5) retours 12. Dans ce cas:

  • Partielle de l'application de la fonction Add avec une valeur 7 va nous donner une nouvelle fonction de sortie. Cette fonction prend 1 nombre en entrée et retourne un nombre. En tant que tel:

    Partial(Add, 7); // returns a function f2 as output
    
                     // f2 takes 1 number as input and returns a number as output
    

    Donc, nous pouvons faire ceci:

    f2 = Partial(Add, 7);
    f2(5); // returns 12;
           // f2(7)(5) is just a syntactic shortcut
    
  • Lancer la fonction Add va nous donner une nouvelle fonction de sortie. La fonction en elle-même dure 1 nombre en entrée et sorties encore une autre nouvelle fonction. Cette troisième fonction prend alors 1 nombre en entrée et renvoie un nombre en sortie. En tant que tel:

    Curry(Add); // returns a function f2 as output
    
                // f2 takes 1 number as input and returns a function f3 as output
                // i.e. f2(number) = f3
    
                // f3 takes 1 number as input and returns a number as output
                // i.e. f3(number) = number
    

    Donc, nous pouvons faire ceci:

    f2 = Curry(Add);
    f3 = f2(7);
    f3(5); // returns 12
    

En d'autres termes, "nourrissage" et "application partielle" sont deux totalement différentes fonctions. Nourrissage prend exactement 1 entrée, alors que l'application partielle prend 2 (ou plus) des entrées. Même s'ils sont tous deux de retour d'une fonction, comme la production, les fonctions sont totalement différentes formes comme démontré ci-dessus.

58voto

dodgy_coder Points 2778

Note: ceci a été pris de F# les Bases d'un excellent article d'introduction .NET développeurs d'entrer dans la programmation fonctionnelle.

Nourrissage moyens de briser une fonction avec beaucoup d'arguments dans une série des fonctions qui prennent chacun un argument et en fin de compte produire de l' même résultat que la fonction originale. Nourrissage est probablement le plus difficile sujet pour les développeurs de nouvelles à la programmation fonctionnelle, en particulier parce qu'il elle est souvent confondue avec l'application partielle. Vous pouvez voir à la fois au travail dans cet exemple:

let multiply x y = x * y    
let double = multiply 2
let ten = double 5

Immédiatement, vous devriez voir le comportement qui est différent de la plupart des des langages impératifs. La deuxième instruction crée une nouvelle fonction appelé double par le passage d'un argument à une fonction qui prend deux. Le résultat est une fonction qui accepte un argument de type int et les rendements de la même résultat que si vous aviez fait appel à multiplier avec x égal à 2 et y égale à celle de l'argument. En termes de comportement, c'est la même chose que ce code:

let double2 z = multiply 2 z

Souvent, les gens à tort de dire que multiplier est le curry de forme double. Mais ce n'est qu'un peu vrai. La fonction multiply est préparé, mais ce qui se passe quand elle est définie, car les fonctions de F# sont au curry par par défaut. Lorsque la double fonction est créée, il est plus juste de dire que la fonction multiply est partiellement appliquée.

La fonction multiply est vraiment une série de deux fonctions. La première la fonction prend un int en argument et renvoie une autre fonction, effectivement la liaison de x à une valeur spécifique. Cette fonction accepte aussi un argument int ce que vous pouvez penser que la valeur de lier à y. Après l'appel de cette deuxième fonction, x et y sont liés, de sorte que le résultat est le produit de x et y définies dans le corps de la double.

Pour créer le double, la première fonction dans la chaîne de multiplier fonctions est évalué à appliquer partiellement multiplier. Le résultant la fonction est donnée le nom de double. Lors d'un double est évalué, il utilise son argument avec l'application partielle de la valeur afin de créer le résultat.

38voto

Jon Skeet Points 692016

Question intéressante. Après un peu de recherche, "Partielle de la Fonction de Demande est de ne pas lancer" a donné la meilleure explication que j'ai trouvé. Je ne peux pas dire que la pratique la différence est particulièrement évident pour moi, mais je ne suis pas un FP expert...

Un autre utile-à la recherche de la page (qui je l'avoue je n'ai pas lu encore) est "Nourrissage et l'Application Partielle avec Java Fermetures".

Il ne ressemble à ce qui est largement confondu paire de termes, vous l'esprit.

18voto

Ji Han Points 251

J'ai répondu à cette question dans un autre thread http://stackoverflow.com/a/12846865/1685865 . En bref, partielles de la fonction de demande est à propos de la fixation des arguments d'une fonction multivariable à céder d'une autre fonction avec moins d'arguments, tandis que le Nourrissage est sur la façon de transformer une fonction de N arguments dans une fonction unaire qui retourne une fonction unaire...[Un exemple de Nourrissage est indiqué à la fin de ce post.]

Nourrissage est surtout un intérêt théorique: on peut exprimer les calculs en utilisant uniquement des fonctions unaires (c'est à dire chaque fonction unaire). Dans la pratique, et comme sous-produit, c'est une technique qui peut faire beaucoup de pratique (mais pas tous) les applications fonctionnelles trivial, si la langue a des fonctions curryfiées. Encore une fois, il n'est pas le seul moyen de mettre en œuvre les applications partielles. Donc, vous pourriez rencontrer des scénarios où l'application partielle est fait d'une autre manière, mais les gens sont croyant que c'est comme Lancer.

(Exemple de Nourrissage)

Dans la pratique, on ne serait pas juste écrire

lambda x: lambda y: lambda z: x + y + z

ou l'équivalent en javascript

function (x) { return function (y){ return function (z){ return x + y + z }}}

au lieu de

lambda x, y, z: x + y + z

pour l'amour de Nourrissage.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X