Currying consiste à convertir une seule fonction de n arguments en n fonctions avec un seul argument chacune. Étant donné la fonction suivante:
function f(x,y,z) { z(x(y));}
Au curry, devient:
function f(x) { lambda(y) { lambda(z) { z(x(y)); } } }
Pour obtenir l'application complète de f (x, y, z), vous devez procéder comme suit:
f(x)(y)(z);
De nombreux langages fonctionnels vous permettent d'écrire f x y z
. Si vous appelez uniquement f x y
ou f (x) (y), vous obtenez une fonction partiellement appliquée - la valeur de retour est une fermeture de lambda(z){z(x(y))}
avec les valeurs transmises de x et y à f(x,y)
.
Une façon d'utiliser l'application partielle consiste à définir les fonctions comme des applications partielles de fonctions généralisées, comme fold :
function fold(combineFunction, accumulator, 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(accumulator,list) {/*...*/}
f(0,list) //returns 10
@g = f(0) //same as sum
g(list) //returns 10
La façon la plus simple de voir comment ils diffèrent est de considérer un exemple réel . Supposons que nous ayons une fonction
Add
qui prend 2 nombres en entrée et renvoie un nombre en sortie, par exemple lesAdd(7, 5)
retours12
. Dans ce cas:L'application partielle de la fonction
Add
avec une valeur7
nous donnera une nouvelle fonction en sortie. Cette fonction elle-même prend 1 nombre en entrée et produit un nombre. En tant que tel:Nous pouvons donc le faire:
Currying la fonction
Add
nous donnera une nouvelle fonction en sortie. Cette fonction elle-même prend 1 numéro en entrée et génère 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:Nous pouvons donc le faire:
En d'autres termes, "currying" et "partial application" sont deux fonctions totalement différentes. Le curry prend exactement 1 entrée, tandis que l'application partielle prend 2 (ou plus) entrées.
Même si elles renvoient toutes deux une fonction en sortie, les fonctions renvoyées sont de formes totalement différentes, comme illustré ci-dessus.
la source
n-ary
en(x - n)-ary
, currying den-ary
enn * 1-ary
. Une fonction partiellement appliquée a une portée réduite (d'application), c'est-à-dire qu'elleAdd7
est moins expressive queAdd
. En revanche, une fonction au curry est aussi expressive que la fonction d'origine.f2(7)(5) is just a syntactic shortcut
? (Je sais très peu.) Nef2
contient pas déjà / "savoir" 7?curry
implémentation quelque part (ne pense pas qu'elle soit dedansfunctools
)Remarque: cela a été tiré de F # Basics, un excellent article d'introduction pour les développeurs .NET qui se lancent dans la programmation fonctionnelle.
la source
Question interessante. Après un peu de recherche, «l'application de fonction partielle ne curry pas» a donné la meilleure explication que j'ai trouvée. Je ne peux pas dire que la différence pratique est particulièrement évidente pour moi, mais je ne suis pas un expert en PF ...
Une autre page intéressante (que j'avoue n'avoir pas encore entièrement lue) est "Currying and Partial Application with Java Closures" .
Il semble que ce soit une paire de termes largement confuse, rappelez-vous.
la source
J'ai répondu à cela dans un autre fil https://stackoverflow.com/a/12846865/1685865 . En bref, l'application d'une fonction partielle consiste à corriger certains arguments d'une fonction multivariable donnée pour produire une autre fonction avec moins d'arguments, tandis que Currying consiste à transformer une fonction de N arguments en une fonction unaire qui renvoie une fonction unaire ... [Un exemple de Le curry est montré à la fin de ce post.]
Le curry est principalement d'intérêt théorique: on peut exprimer des calculs en utilisant uniquement des fonctions unaires (c'est-à-dire que chaque fonction est unaire). En pratique et en tant que sous-produit, c'est une technique qui peut rendre triviales de nombreuses applications fonctionnelles partielles utiles (mais pas toutes), si le langage a des fonctions curry. Encore une fois, ce n'est pas le seul moyen de mettre en œuvre des applications partielles. Vous pouvez donc rencontrer des scénarios où une application partielle est effectuée d'une autre manière, mais les gens la confondent avec Currying.
(Exemple de curry)
En pratique, on n’écrirait pas
ou le javascript équivalent
au lieu de
pour le plaisir de Currying.
la source
Le curry est une fonction d' un argument qui prend une fonction
f
et renvoie une nouvelle fonctionh
. Notez queh
prend un argument deX
et renvoie une fonction qui correspondY
àZ
:Une application partielle est une fonction de deux (ou plus) arguments qui prend une fonction
f
et un ou plusieurs arguments supplémentairesf
et renvoie une nouvelle fonctiong
:La confusion survient car avec une fonction à deux arguments, l'égalité suivante est vérifiée:
Les deux côtés produiront la même fonction à un argument.
L'égalité n'est pas vraie pour les fonctions d'arité supérieure, car dans ce cas, le curry renvoie une fonction à un argument, tandis que l'application partielle renvoie une fonction à plusieurs arguments.
La différence réside également dans le comportement, alors que le curry transforme récursivement toute la fonction d'origine (une fois pour chaque argument), l'application partielle n'est qu'un remplacement en une étape.
Source: Wikipedia Currying .
la source
La différence entre le curry et l'application partielle peut être mieux illustrée par cet exemple JavaScript suivant:
Une application partielle se traduit par une fonction d'arité plus petite; dans l'exemple ci-dessus,
f
a une arité de 3 alors qu'ellepartial
n'a qu'une arité de 2. Plus important encore, une fonction partiellement appliquée retournerait immédiatement le résultat lors de son appel , pas une autre fonction le long de la chaîne de curry. Donc, si vous voyez quelque chose commepartial(2)(3)
ça, ce n'est pas une application partielle en réalité.Lectures complémentaires:
la source
Réponse simple
Curry: permet d'appeler une fonction, de la diviser en plusieurs appels, en fournissant un argument par appel.
Partiel: permet d'appeler une fonction, de la diviser en plusieurs appels et de fournir plusieurs arguments par appel.
Conseils simples
Les deux vous permettent d'appeler une fonction fournissant moins d'arguments (ou, mieux, les fournissant cumulativement). En fait, les deux lient (à chaque appel) une valeur spécifique à des arguments spécifiques de la fonction.
La vraie différence est visible lorsque la fonction a plus de 2 arguments.
Simple e (c) (exemple)
(en Javascript)
pourquoi toujours passer les arguments, comme le contexte et les rappels, s'ils seront toujours les mêmes? Liez juste quelques valeurs pour la fonction
et l'appeler sur subject1 et foobar avec
Confortable, n'est-ce pas? 😉
Avec le curry, vous devez passer un argument à la fois
Avertissement
J'ai sauté toutes les explications académiques / mathématiques. Parce que je ne le sais pas. Peut-être que cela a aidé 🙃
la source
J'ai beaucoup posé cette question en apprenant et on m'a depuis posé de nombreuses fois. La façon la plus simple de décrire la différence est que les deux sont les mêmes :) Laissez-moi vous expliquer ... il y a évidemment des différences.
L'application partielle et le curry impliquent de fournir des arguments à une fonction, peut-être pas tous en même temps. Un exemple assez canonique est d'ajouter deux nombres. En pseudocode (en fait JS sans mots-clés), la fonction de base peut être la suivante:
Si je voulais une fonction "addOne", je pourrais l'appliquer partiellement ou la curry:
Maintenant, les utiliser est clair:
Alors quelle est la différence? Eh bien, c'est subtil, mais une application partielle implique de fournir des arguments et la fonction retournée exécutera ensuite la fonction principale lors de la prochaine invocation tandis que le curry continuera d'attendre jusqu'à ce qu'il ait tous les arguments nécessaires:
En bref, utilisez une application partielle pour préremplir certaines valeurs, sachant que la prochaine fois que vous appellerez la méthode, elle s'exécutera, laissant non défini tous les arguments non fournis; utilisez le curry lorsque vous souhaitez renvoyer continuellement une fonction partiellement appliquée autant de fois que nécessaire pour remplir la signature de la fonction. Un dernier exemple artificiel:
J'espère que cela t'aides!
MISE À JOUR: Certains langages ou implémentations lib vous permettront de passer une arité (nombre total d'arguments en évaluation finale) à l'implémentation d'application partielle qui peut confondre mes deux descriptions dans un désordre déroutant ... mais à ce stade, les deux techniques sont largement interchangeable.
la source
Pour moi, une application partielle doit créer une nouvelle fonction où les arguments utilisés sont complètement intégrés dans la fonction résultante.
La plupart des langages fonctionnels implémentent le curry en renvoyant une fermeture: ne pas évaluer sous lambda lorsqu'il est partiellement appliqué. Donc, pour que l'application partielle soit intéressante, nous devons faire la différence entre le curry et l'application partielle et considérer l'application partielle comme le curry plus l'évaluation sous lambda.
la source
Je pourrais me tromper ici, car je n'ai pas une solide formation en mathématiques théoriques ou en programmation fonctionnelle, mais de ma brève incursion en FP, il semble que le curry a tendance à transformer une fonction de N arguments en N fonctions d'un argument, tandis que l'application partielle [en pratique] fonctionne mieux avec des fonctions variadiques avec un nombre indéterminé d'arguments. Je sais que certains des exemples des réponses précédentes défient cette explication, mais cela m'a le plus aidé à séparer les concepts. Considérez cet exemple (écrit en CoffeeScript pour la concision, mes excuses si cela prête à confusion, mais veuillez demander des éclaircissements, si nécessaire):
C'est évidemment un exemple artificiel, mais notez que l'application partielle d'une fonction qui accepte n'importe quel nombre d'arguments nous permet d'exécuter une fonction mais avec quelques données préliminaires. Curryer une fonction est similaire mais nous permet d'exécuter une fonction à N paramètres en morceaux jusqu'à ce que, mais seulement jusqu'à, tous les N paramètres soient pris en compte.
Encore une fois, c'est mon point de vue sur les choses que j'ai lues. Si quelqu'un n'est pas d'accord, j'apprécierais un commentaire sur la raison plutôt qu'une baisse immédiate. De plus, si le CoffeeScript est difficile à lire, veuillez visiter coffeescript.org, cliquez sur "essayer coffeescript" et collez mon code pour voir la version compilée, qui peut (espérons-le) avoir plus de sens. Merci!
la source
Je vais supposer que la plupart des gens qui posent cette question connaissent déjà les concepts de base, il n'est donc pas nécessaire d'en parler. C'est le chevauchement qui est la partie déroutante.
Vous pourrez peut-être utiliser pleinement les concepts, mais vous les comprenez ensemble comme ce flou conceptuel amorphe pseudo-atomique. Ce qui manque, c'est de savoir où se situe la frontière entre eux.
Au lieu de définir ce que chacun est, il est plus facile de souligner uniquement leurs différences - la frontière.
Le curry est lorsque vous définissez la fonction.
L'application partielle est lorsque vous appelez la fonction.
L'application est mathématique pour appeler une fonction.
Une application partielle nécessite d'appeler une fonction curry et d'obtenir une fonction comme type de retour.
la source
Il y a d'autres bonnes réponses ici, mais je crois que cet exemple (selon ma compréhension) en Java pourrait être bénéfique pour certaines personnes:
Le currying vous donne donc une fonction à un argument pour créer des fonctions, où application partielle crée une fonction wrapper qui code en dur un ou plusieurs arguments.
Si vous souhaitez copier et coller, les éléments suivants sont plus bruyants mais plus conviviaux, car les types sont plus indulgents:
la source
En écrivant ceci, j'ai confondu le curry et le non curry. Ce sont des transformations inverses sur les fonctions. Peu importe ce que vous appelez, tant que vous obtenez ce que la transformation et son inverse représentent.
Le non-currying n'est pas défini très clairement (ou plutôt, il existe des définitions «conflictuelles» qui captent toutes l'esprit de l'idée). Fondamentalement, cela signifie transformer une fonction qui prend plusieurs arguments en une fonction qui prend un seul argument. Par exemple,
Maintenant, comment transformez-vous cela en une fonction qui prend un seul argument? Vous trichez, bien sûr!
Notez que plus prend désormais un seul argument (qui est composé de deux choses). Super!
À quoi ça sert? Eh bien, si vous avez une fonction qui prend deux arguments et que vous avez une paire d'arguments, il est bon de savoir que vous pouvez appliquer la fonction aux arguments et toujours obtenir ce que vous attendez. Et, en fait, la plomberie pour le faire existe déjà, de sorte que vous n'avez pas à faire des choses comme la correspondance explicite de motifs. Tout ce que tu dois faire est:
Alors, quelle est l'application de fonction partielle? C'est une manière différente de transformer une fonction en deux arguments en une fonction avec un seul argument. Cela fonctionne cependant différemment. Encore une fois, prenons (+) comme exemple. Comment pourrions-nous en faire une fonction qui prend un seul Int comme argument? On triche!
C'est la fonction qui ajoute zéro à tout Int.
ajoute 1 à tout Int. Etc. Dans chacun de ces cas, (+) est "partiellement appliqué".
la source