next up previous contents index
Next: Symboles, séparateurs, identificateurs Up: Quelques éléments de Caml Previous: Fonctions

Fonctionnelles

  Il n'y a pas de contraintes sur les arguments et résultats des procédures et des fonctions: les arguments et résultats fonctionnels sont donc autorisés. Une bonne illustration consiste à écrire une procédure de recherche d'une racine d'une fonction sur un intervalle donné. La procédure zéro prend une fonction f en argument (et pour cette raison on dit que zéro est une fonctionnelle). Définissons d'abord une fonction auxiliaire qui calcule la valeur absolue d'un flottant.    

let abs x = if x >= 0.0 then x else -. x;;

Nous notons à l'occasion que les nombres flottants comportent obligatoirement un point, même . Les opérations sur les nombres flottants sont également distinctes de celles des nombres entiers, puisqu'elles sont systématiquement suffixées par un point (sauf les comparaisons). Notre fonctionnelle s'écrit alors:

let trouve_zéro f a b epsilon max_iterations =
 let rec trouve x y n =
  if abs (y -. x) < epsilon || n >= max_iterations then x
  else
   let m = (x +. y) /. 2.0 in
   if (f m > 0.0) = (f x > 0.0)
   then trouve m y (n + 1)
   else trouve x m (n + 1) in
 trouve a b 1;;
let zéro f a b = trouve_zéro f a b 1.0E-7 100;;

Remarquons la définition locale de la fonction récursive trouve, qu'on applique ensuite avec les arguments a, b et 1. Si on a des difficultés à comprendre ce style fonctionnel, voici la même fonction en version impérative (avec une boucle while que nous verrons plus loin):

let zéro f a b =
 let epsilon = 1.0E-7
 and nmax  = 100 in
 let n = ref 1
 and m = ref ((a +. b) /. 2.0) in
 let x = ref a
 and y = ref b in
 while abs (!y -. !x) > epsilon && !n < nmax do
  m := (!x +. !y) /. 2.0;
  if (f !m > 0.0) = (f !x > 0.0)
   then x := !m
   else y := !m;
  n := !n + 1
 done;
 !x;;

Le type inféré par Caml pour zéro est (float -> float) -> float -> float -> float qui indique bien que le premier argument est une fonction des flottants dans les flottants. Utilisons la fonctionnelle zéro pour trouver un zéro de la fonction logarithme entre 1/2 et 3/2:

#open "printf";;
#let log10 x = log x /. log 10.0;;
log10 : float -> float = <fun>
#printf "le zéro de log10 est %f\n" (zéro log10 0.5 1.5);;
le zéro de log10 est 1.000000
- : unit = ()

Les arguments fonctionnels sont naturels et rendent souvent l'écriture plus élégante. Il faut noter que l'efficacité du programme n'en souffre pas forcément, surtout dans les langages fonctionnels qui optimisent la compilation des fonctions et de leurs appels.


next up previous contents index
Next: Symboles, séparateurs, identificateurs Up: Quelques éléments de Caml Previous: Fonctions

1/11/1998