|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
![]() ![]() |
Bonsoir,
Je sais pas si je suis dans la bonne section j'ai hésité a poster Je suis tombé sur une méthode de programmation donc cela ne concerne pas vraiment de langage en particulier, et c'est uniquement pour moi, pour ma culture. Donc en clair qu'est ce que la Curryfication ? J'ai bien sur cherché sur google je suis tombé notamment la dessus : http://fr.wikipedia.org/wiki/Curryfication J'ai pas très bien compris la définition mais encore moins quand/pourquoi l'utiliser Si un d'entre pourrait reformuler/expliquer avec un exemple je lui en serais reconnaissant. Par exemple je sous entends un exemple d'utilisation pas de code Merci.
__________________
--- Overcrash Je ne lis pas les codes qui ne sont pas indentés. Merci de les messages utiles en cliquant en bas à droite du message |
|
|
00
|
|
|
#2 | ||
|
Expert Confirmé Sénior
![]() |
Déjà, c'est de la programmation fonctionnelle, donc impossible à faire directement dans des langages comme C ou C++: il est question de générer des fonctions en run-time.
Si j'ai bien compris, la currification, c'est remplacer une fonction genre ajouter(x, y) par un truc du genre creer_fonction_ajouter_x(x) qui retourne une fonction. Ainsi, imaginons que je veuille ajouter 3 + 5, au lieu de faire ceci: Code non-currifié :
int resultat = ajouter(3, 5) Code curryfié :
__________________
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant. "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?" Apparently everyone. -- Raymond Chen. Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen. |
||
|
|
10
|
|
|
#3 |
![]() ![]() |
plop,
Ha ok je comprend mieux mais alors ca sert a quoi ? Concrètement ?
__________________
--- Overcrash Je ne lis pas les codes qui ne sont pas indentés. Merci de les messages utiles en cliquant en bas à droite du message |
|
|
00
|
|
|
#4 |
|
Expert Confirmé Sénior
![]() |
Il me semble qu'en programmation fonctionnelle, pratiquement tout est basé sur ce genre de truc. Je ne peux pas t'en dire plus, là: C'est aussi alien pour moi que pour quiconque a grandi avec la programmation impérative.
__________________
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant. "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?" Apparently everyone. -- Raymond Chen. Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen. |
|
|
00
|
|
|
#5 | |||||||
|
Membre du Club
![]() Inscription : octobre 2007 Messages : 34 ![]() |
C'est principalement utilisé pour les fonctions d'ordre supérieur, tel que map, filter ou les fold_left/fold_right.
par exemple pour ajouter 5 à tous les nombres d'une liste de nombre, on va utiliser l'opérateur (+) qui est une fonction qui prend 2 entiers et en renvoit 1, et qui a pour type sous sa forme curryfié : où la flèche représente l'application d'une fonction. L'opération d'ordre supérieure pour transformer les éléments d'une liste s'appelle map, ici décrit pour les listes d'entier uniquement : Elle prend en premier paramètre une fonction qui pour entier donné retourne un autre entier, et une liste. Map retourne une liste d'entier. Au final nous obtenons : Code :
Ici on utilise la curryfication pour grandement simplifier l'écriture. Dans la pratique, on appelle souvent des fonctions plus complexes, conçue pour tirer partie de la curryfication, typiquement placer les arguments de paramétrage au début des paramètres et l'argument "manipulé" à la fin. En respectant cette forme d'écriture, on peut même arriver à créer des "pipeline" de fonction (un peu comme en shell), où l'on combine des fonctions curryfiée, en laissant juste le dernier argument manquant. Par exemple en Haskell, on peut écrire : Code :
C'est très puissant et pratique d'utilisation, mais il faut juste s'habituer un peu au mécanisme, un peut "alien" au début, indispensable par la suite. Citation:
Code :
|
|||||||
|
|
30
|
|
|
#6 |
|
Expert Confirmé Sénior
![]() |
^C'est ce que je voulais dire par "pas directement": Pour faire ça en C++, tu dois reproduire toutes les fonctions et le moteur pour les évaluer.
__________________
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant. "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?" Apparently everyone. -- Raymond Chen. Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen. |
|
|
00
|
|
|
#7 | |||
|
Membre du Club
![]() Inscription : octobre 2007 Messages : 34 ![]() |
Citation:
Code :
|
|||
|
|
00
|
|
|
#8 | ||||
|
Membre chevronné
![]() Inscription : mars 2010 Messages : 281 ![]() |
Ah, la curryfication, en voilà un sujet sympa ! (note aux modos: un petit lien depuis le sous forum "langage fonctionnel" attirerait sans doute plus de gens qui comprennent bien)
Je vais essayer de me concentrer sur la curryfication et non sur les types par exemple, même si le liens est souvent fort. Pour mes exemples, j'utiliserai du caml (je n'ai pas testé le code, donc il ne faut pas s'étonner si ça ne compile pas et s'il y a des erreurs de syntaxe. Mais l'idée sera là) Commençons par voir comment on défini une fonction en caml: Le mot clé let dit que l'on défini quelque chose. Là, c'est une fonction (plus1) qui attends un argument x, et retourne x + 1. Pour appeler cette fonction, rien de plus simple. plus1 41 vaut 42. On remarquera qu'on n'utilise pas de parenthèse. Supposons maintenant qu'on veuille définir une fonction à 2 arguments. Il est possible de faire quelque chose comme comme dans la majorité des langages. Néanmoins, il est d'usage de faire Et pour appeler cette fonction : plus 20 22 retournera 42. Là non plus, pas de parenthèse. C'est ce qu'on appelle une fonction "curryfiée". Pourquoi ? A première vu, ça semble être un simple changement de syntaxe, f(x, y) contre f x y. Mais la différence de syntaxe semble impliquer quelque chose de bien intéressant. On devrait pouvoir s'arrêter après le x, en écrivant juste f x (ce qui ne semble pas possible dans l'autre cas. Ecrire f(x, n'a pas trop de sens !). Qu'est ce que ça peut bien vouloir dire ? Supposons qu'on récupère cette application partielle Il "manque un bout" pour avoir l'application complète. Et bien ça tombe bien, on peut finir de l'appliquer. foo 30 === plus 12 30 === 42. On a ici le plus grand intérêt de la curryfication, si ce n'est le seul, à savoir l'application partielle, qui permet de créer une "nouvelle" fonction, qui est comme l'ancienne, mais avec quelques arguments déjà fournis. Est ce que c'est une sorte de magie ad-hoc qui fait qu'on peut appliquer partiellement les fonctions ? Bien sur que non ! En fait, d'un point de vue sémantique (c'est à dire le sens que l'on donne à un programme), toutes les fonctions n'ont qu'un seul argument. Mais une fonction peut très bien retourner une autre fonction comme résultat ! Donc quand on définie ce que l'on défini réellement, c'est une fonction mult qui attend un argument x et qui retourne une fonction (anonyme) qui attend un argument y et qui retourne y * x. (J'arrête tout de suite ceux qui vont pousser des haut cris "mais c'est super inefficace !", ce n'est pas comme ça que c'est implémenté en caml ! Quand une fonction est totalement appliqué, c'est un appel de fonction à plusieurs arguments qui est implémenté via une "décurryfication". Aucune différence d'efficacité.) Plus précisément, on pourrait écrire mult de la façon suivante : où fun x -> blah est la fonction qui attend un argument x et retourne blah. Et donc quand on écris ensuite mult 21 2, c'est en fait (mult 21) 2 === (fun y -> y * 21) 2 === 2 * 21 === 42. Donc aucune "magie" derrière la curryfication, juste une sémantique liée au fait qu'on peut retourner une fonction. Maintenant quels sont les exemples d'utilisation ? Comme le disait Twinside, c'est souvent lié aux "fonctions d'ordre supérieur". Par exemple la fonction List.map en caml prend en argument une fonction et une liste, applique la fonction a chaque élément de la liste, et retourne la liste des résultat. Par exemple List.map plus1 [1;2;3] va retourner la liste [2;3;4]. Imaginons maintenant que je ne veuille pas ajouter 1, mais multiplier par 2. Je pourrais d'abord définir une fonction mult2, puis appeler List.map mult2 [1;2;3]. Mais il y a plus simple ! J'ai déjà une fonction mult, qui multiplie deux nombres. Donc il suffit d'écrire List.map (mult 2) [1;2;3] pour obtenir [2;4;6] ! Maintenant, est ce tout ? Oh que non Supposons que l'on veulent écrire une fonction append_line qui prend un nom de fichier et une chaine de caractères, ouvre le fichier, et écrit la ligne dedans. Ca donnerait sans doute quelque chose comme Code :
On a notre fonction, et on commence à l'utiliser à pas mal d'endroit dans le code. Dont une fois, ou on a une liste de chaine à écrire, et on a List.map (append_line "monFichier.txt" lst. Et là on constate qu'à chaque élément de la liste, on va appliquer la fonction, qui va créer une nouveau descripteur de fichier pour "monFichier.txt", ajouter une chaine, et jeter le descripteur ! Peut on faire mieux ? Hé oui, comme suit : Code :
Bref, la curryfication permet en plus d'effectuer un calcul entre l'application de deux arguments, ce qui peut être tout particulièrement puissant. Si tu as besoin d'autres précisions, n'hésite pas à demander |
||||
|
|
10
|
|
|
#9 |
![]() ![]() Damien GuichardInscription : juin 2007 Messages : 1 512 ![]() |
C'est une question archi-débattue sur dvp, ici par exemple.
__________________
Du même auteur: le cours OCaml, le dernier article publié, le projet, le blog dvp et le jeu vidéo. Avant de poser une question je lis les règles du forum. |
|
00
|
|
|
#10 | |||
|
Membre chevronné
![]() Inscription : mars 2010 Messages : 281 ![]() |
Citation:
Citation:
Citation:
|
|||
|
|
00
|
|
|
#11 |
![]() ![]() |
Bonsoir,
Tout d'abords je vous remercie pour le temps consacré a la question et aux différents posteur qui m'ont aidé a comprendre cette notions super flou a la base En revanche il est vrai que mon post a plus sa place sur cette section : http://www.developpez.net/forums/f51...-fonctionnels/ Mais je savais pas que le langage fonctionnelle était un "type" je le saurai la prochaine fois Merci encore
__________________
--- Overcrash Je ne lis pas les codes qui ne sont pas indentés. Merci de les messages utiles en cliquant en bas à droite du message |
|
|
00
|
Copyright © 2000-2013 - www.developpez.com