Programmation Fonctionnelle
Stefano Guerrini
stefano.guerrini@univ-paris13.fr
http://www.lipn.univ-paris13.fr/~guerrini
LIPN - Institut Galil´ee, Universit´e Paris Nord 13
Licence Info 3
evrier 2013
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 1 / 131
Les fonctions
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 25 / 131
Les fonctions Fonctions n-aires
Fonction n-aire ou sur n-uplets
Une fonction binaire
#letfxy=x+y;;
val f : int -> int -> int = <fun>
en eet, c’est une fonction unaire qui renvoie une fonction unaire
On peut d´efinir une fonction binaire en utilisant un couple
#letg(x,y)=x+y;;
val g : int * int -> int = <fun>
en eet, cette fonction est une fonction unaire sur une couple
La d´efinition pr´ec´edente est ´equivalente `a
#letgp=fstp+sndp;;
val g : int * int -> int = <fun>
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 26 / 131
Les fonctions Fonctions n-aires
Exemples
On peut toujours transformer une fonction binaire en une fonction qui prend
ses deux arguments comme ´el´ements d’une couple :
#letcurryf(x,y)=fxy;;
val curry : (’a -> ’b -> ’c) -> ’a * ’b -> ’c = <fun>
#letf1xy=x+y;;
val f1 : int -> int -> int = <fun>
#f134;;
-:int=7
# let f2 = curry f1;;
val f2 : int * int -> int = <fun>
# f2 (3,4);;
-:int=7
#f334;;
-:int=7
On peux aussi bien d´efinir la fonction inverse de curry
# let uncurry f x y = f (x,y);;
val uncurry : (’a * ’b -> ’c) -> ’a -> ’b -> ’c = <fun>
# let f3 = uncurry f2;;
val f3 : int -> int -> int = <fun>
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 27 / 131
Les fonctions La r´ecursion
Fonctions r´ecursives
Une d´efinition de fonction peut ˆetre r´ecursive, mais il faut ajouter le mot cl´e
rec `a let
#letrecexpx=
if (x = 0) then 1
else if (x mod 2 = 1) then (exp (x/2)) * (exp (x/2)) * 2
else (exp (x/2)) * (exp (x/2));;
val exp : int -> int = <fun>
La d´efinition pr´ec´edente est tr`es inecace car elle ´evalue deux fois la mˆeme
expression r´ecursive dans chaque branche du cas x>0.
Pour ´eviter ce type de probl`emes on peut d´efinir des noms locaux
#letrecexpx=
if (x = 0) then 1
else let h = exp (x/2) in
if (x mod 2 = 1) then h * h * 2
else h * h;;
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 28 / 131
Les fonctions La r´ecursion
Fibonacci
La fonction de Fibonacci
# let rec fib n = if n < 2 then 1 else (fib (n-1) + fib (n-2));;
val fib : int -> int = <fun>
La pr´ec´edente fonction n’est pas trop ecace : le probl`eme est qu’il y a une
double appel de la fonction r´ecursive.
Essayez de calculer fib 40;;
On peut pourtant coder de fa¸con “r´ecursive” la version “it´erative” de
Fibonacci qui calcul au meme temps fib n;; et fib (n-1);;
let rec fib n =
if n = 0
then (1,0)
else let p = fib (n-1)
in let x = fst p
and y = snd p
in (x+y, x);;
let fibonacci n =
let rec fib n =
if n = 0
then (1,0)
else let p = fib (n-1)
in let x = fst p
and y = snd p
in (x+y, x)
in fst (fib n);;
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 29 / 131
Les fonctions La r´ecursion
Fonctions ieratives
On n’a pas encore de commandes pour l’it´eration (while ou repeat).
Mais la possibilit´e de d´efinir des fonctions d’ordre sup´erieure (fonctions qui
prennent comme arguments des fonctions et revoient des fonctions comme
esultat) nous permet de d´efinir une fonctionnelle iter qui prend
1un entier n,
2une valeur f0de type
(par exemple : un entier),
3une fonction f1:!
(par exemple : une fonction sur les entiers qui double son argument)
4et calcul fn
1(f0)
(qu’est-ce qu’on obtient avec les exemples pec´edentes ?)
let rec iter n f0 f1 =
if n = 0
then f0
else f1 (iter (n-1) f0 f1);;
let dup x = 2 * x;;
let exp2 n =
fst (iter n 1 dup);;
On peut aussi bien utiliser iter pour d´efinir fibonacci :
let fibstep (x,y) = (x+y, x);; let fibonacci n =
fst (iter n (1,0) fibstep);;
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 30 / 131
Les fonctions Les d´eclarations
D´eclarations globales et d´eclarations locales
Une d´eclaration globale associe un nom `a une valeur
#letx=3*4;;
val x : int = 12
En r´eponse `a une d´eclaration globale, la boucle ache l’eet que la
eclaration a eu sur l’environnement globale (en ajoute au type et `a la valeur
de l’expression).
Dans l’exemple, val x indique que
1le nom xa ´et´e ajout´e `a l’environnement ;
2que le nom xest associ´e `a une valeur.
Dans une d´eclaration locale
let x = 3 in x + 2;;
le nom d´eclar´e n’est connu que dans l’expression qui suive le in.
Une d´eclaration locale peut red´efinir localement un nom global
#letx=2;;
val x : int = 2
#letx=3inx;;
-:int=3
#x;;
-:int=2
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 31 / 131
Les fonctions Les d´eclarations
D´eclarations et expressions
Une d´eclaration locale est une expression et on peut l’utiliser comme une
autre expression quelconque du mˆeme type
#4*letx=2inx+4;;
-:int=24
Une d´eclaration globale n’est pas une expression
#4*letx=2;;
Characters 14-16:
4*letx=2;;
^^
Error: Syntax error
Une d´eclaration globale peut ˆetre utiliser seulement dans des contextes
particuliers, par exemple, comme commande pour la boucle.
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 32 / 131
Les fonctions Les d´eclarations
Noms OCaml vs. variables C
Les noms OCaml et les variables C sont des objets de natures compl`etement
di´erentes.
IEn OCaml, une variable est un nom pour une valeur, alors qu’en C une
variable est un nom pour une case m´emoire.
IEn OCaml, il est donc hors de question de pouvoir changer la valeur d’une
variable.
ILa d´eclaration globale (ou locale, voir plus loin) d’OCaml, n’a rien `a voir avec
l’aectation du C.
IPour obtenir des variables OCaml avec un comportement similaire aux
variables C il faut utiliser
Fdes donn´ees d’un type particulier, les enregistrements `a champs modifiables,
Fet les r´ef´erences (ou pointers).
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 33 / 131
Les fonctions eclarations simultan´ees et recursion mutuelle
D´eclarations simultan´ees
Dans une d´eclaration globale ou locale on peut d´efinir plusieurs variable au
mˆeme temps et en parall`ele dans une eclaration simultan´ee.
#letx=3andy=4;;
val x : int = 3
val y : int = 4
#letx=yandy=xin(x,y);;
-:int*int=(4,3)
Dans une d´eclaration simultan´ee les expressions sont ´evalu´ees avant d’associer
les noms de la d´eclaration aux valeurs des expressions correspondantes.
Une d´eclaration simultan´ee n’est pas ´equivalent `a une chaˆıne de d´eclaration
#letx=yinlety=xin(x,y);;
-:int*int=(4,4)
#lety=xinletx=yin(x,y);;
-:int*int=(3,3)
Dans une chaˆıne de d´eclarations l’ordre est relevant, tandis que dans une
eclaration simultan´ee l’ordre des d´eclarations n’a aucun influence sur le
r´esultat
#lety=xandx=yin(x,y);;
-:int*int=(4,3)
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 34 / 131
Les fonctions eclarations simultan´ees et recursion mutuelle
La r´ecursion mutuelle
Les d´eclarations r´ecursives simultan´ees permettent de d´efinir des fonctions
mutuellement r´ecursives
# let rec isOdd x = if (x = 0) then false else isEven (x-1)
and isEven x = if (x = 0) then true else isOdd (x-1);;
val isOdd : int -> bool = <fun>
val isEven : int -> bool = <fun>
#letrecfx=ifx<=1then1elseg(x+2)
and g x = f (x-3) + 4;;
val f : int -> int = <fun>
val g : int -> int = <fun>
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 35 / 131
1 / 3 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !