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 inefficace 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 f´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 efficace : 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 f´evrier 2013 29 / 131
Les fonctions La r´ecursion
Fonctions it´eratives
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
r´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 pr´ec´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 f´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 affiche l’e↵et que la
d´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 f´evrier 2013 31 / 131