Envoyé par
BlueJack
Wikipedia à propos de la curryfication:
Envoyé par
Wikipedia
En programmation fonctionnelle, la curryfication désigne l'opération qui fait passer d'une fonction à plusieurs arguments à une fonction à un argument et qui retourne une fonction qui prend le reste des arguments.
Je dois t'avouer que j'ai du mal à comprendre.
Reprenons l'exemple de max :
let max x y = if x > y then x else y
Contrairement à l'impression erronée que tu as probablement, ce max n'est pas une fonction à deux arguments... Pour avoir une fonction à deux arguments, similaire à la façon dont max est défini dans la plupart des autres langages, il faudrait écrire :
let max (x,y) = if x > y then x else y
Comparons les types de ces deux fonctions (pour simplifier on fixera le type manipulé à int, bien que max soit en fait polymorphe), la seconde version a le type :
val max : (int, int) -> int
C'est un type qui ressemble pas mal à ce que tu peux voir dans d'autres langages : max prend deux entiers en argument et renvoie un entier.
Maintenant la première version :
val max : int -> int -> int
En fait il y a des parenthèses implicites dues à l'associativité de (->) :
val max : int -> (int -> int)
Dans cette version, max est donc une fonction qui prend un entier en argument et renvoie une deuxième fonction qui prend un entier en argument et renvoie un entier...
En fait notre premier code aurait pu être écrit :
let max x = fun y -> if x > y then x else y
et dans la plupart des langages qui supporte les fonctions anonymes c'est ainsi qu'il aurait dû être écrit, la notation initialement employée n'est qu'un sucre syntaxique offert par OCaml pour écrire plus facilement des fonctions curryfiée.
En effet, toute fonction à plusieurs arguments peut-être soumise à cette même transformation en fonction à un argument qui renvoie une fonction et cette forme curryfiée présente de nombreux avantages, dont le fait qu'elle rende très facile l'application partielle d'une fonction pourvu que l'ordre des arguments s'y prête. Par exemple, si on veut corriger une liste d'échantillon en ramenant ceux qui sont trop bas à une valeur minimale, on peut écrire avec la fonction curryfiée :
let newSamples = List.map (max 5) samples
Alors qu'avec la version "classique" de max, il faut utiliser une fonction anonyme :
let newSamples = List.map (fun y -> max (5,y)) samples
Le gain est minimal dans ce cas, mais en favorisant la définition de fonction curryfiées par défaut grâce à son sucre syntaxique, OCaml favorise en fait un style de programmation plus orienté vers la manipulation de fonctions et les fonctions d'ordre supérieur (qui prenne des fonctions en paramètre, comme fold_left), un style fonctionnel en bref !
--
Jedaï
Partager