Lycée Thiers Année Option Informatique

Documents pareils
Recherche dans un tableau

Classes et Objets en Ocaml.

length : A N add : Z Z Z (n 1, n 2 ) n 1 + n 2

Algorithmique et Programmation, IMA

Machines virtuelles fonctionnelles (suite) Compilation ML Java

# let rec concat l1 l2 = match l1 with [] -> l2 x::l 1 -> x::(concat l 1 l2);; val concat : a list -> a list -> a list = <fun>

Cours de Programmation 2

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Cours No 3 : Identificateurs, Fonctions, Premières Structures de contrôle.

modules & compilation

Cours 1 : La compilation

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme


Présentation du langage et premières fonctions

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Les structures. Chapitre 3

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Utilisation d objets : String et ArrayList

SNT4U16 - Initiation à la programmation TD - Dynamique de POP III - Fichiers sources

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Programmer en JAVA. par Tama

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Java Licence Professionnelle CISII,

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Vérification de programmes et de preuves Première partie. décrire des algorithmes

Rappels Entrées -Sorties

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Langage propre à Oracle basé sur ADA. Offre une extension procédurale à SQL

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Les chaînes de caractères

Plan du cours : Zippers. Des fonctions sur les listes avec position. Des fonctions sur les listes avec position

TP1 : Initiation à Java et Eclipse

LES TYPES DE DONNÉES DU LANGAGE PASCAL

Chap III : Les tableaux

Premiers Pas en Programmation Objet : les Classes et les Objets

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Sub CalculAnnuite() Const TITRE As String = "Calcul d'annuité de remboursement d'un emprunt"

Langage SQL (1) 4 septembre IUT Orléans. Introduction Le langage SQL : données Le langage SQL : requêtes

Module Administration BD Chapitre 1 : Surcouche procédurale dans les SGBDS

F. Barthélemy. 17 mai 2005

Conventions d écriture et outils de mise au point

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Notions fondamentales du langage C# Version 1.0

TP 1. Prise en main du langage Python

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Initiation à l algorithmique

Arbres binaires de recherche

Corrigé des TD 1 à 5

ACTIVITÉ DE PROGRAMMATION

Solutions du chapitre 4

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

TP3 : Manipulation et implantation de systèmes de fichiers 1

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

Analyse de sécurité de logiciels système par typage statique

Expression des contraintes. OCL : Object C o n t r a i n t L a n g u a g e

Chapitre 10. Les interfaces Comparable et Comparator 1

OCL - Object Constraint Language

Java 1.5 : principales nouveautés

INF 321 : mémento de la syntaxe de Java

Serveur d'application Client HTML/JS. Apache Thrift Bootcamp

Chapitre VI- La validation de la composition.

1. Structure d'un programme FORTRAN 95

Objets et Programmation. origine des langages orientés-objet

Cours d algorithmique pour la classe de 2nde

Découverte de Python

ALGORITHMIQUE ET PROGRAMMATION En C

STAGE IREM 0- Premiers pas en Python

Logiciel Libre Cours 2 Fondements: Programmation

Chapitre 2. Eléments pour comprendre un énoncé

Programme Compte bancaire (code)

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

Programmation en Caml pour Débutants

I. Introduction aux fonctions : les fonctions standards

Plan du cours. Historique du langage Nouveautés de Java 7

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

Introduction à l algorithmique et à la programmation M1102 CM n 3

Corrigé des exercices sur les références

Génie Logiciel avec Ada. 4 février 2013

Programmation. fonctionnelle, impérative, logique et orientée objet

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

MICROINFORMATIQUE NOTE D APPLICATION 1 (REV. 2011) ARITHMETIQUE EN ASSEMBLEUR ET EN C

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

Cours d initiation à la programmation en C++ Johann Cuenin

ARDUINO DOSSIER RESSOURCE POUR LA CLASSE

Programmation C++ (débutant)/instructions for, while et do...while

Examen Médian - 1 heure 30

UE Programmation Impérative Licence 2ème Année

Cours 6 : Programmation répartie

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Bases de programmation. Cours 5. Structurer les données

as Architecture des Systèmes d Information

Cours Informatique Master STEP

Paginer les données côté serveur, mettre en cache côté client

Peut-on tout programmer?

Transcription:

Lycée Thiers Année 2017-18 Sup MPSI Option Informatique OCAML - 3 / FILTRAGE / POLYMORPHISME / EXCEPTIONS En utilisant la construction 1. Filtrage par motifs match expr with m 1 expr 1 m n expr n on peut confronter la valeur d une expression à une succession de motifs, jusqu à ce qu une correspondance soit trouvée. C est le filtrage par motifs (pattern matching en anglais) : il sert à reconnaître la forme de cette valeur et permet d orienter le calcul en associant à chaque motif une expression à évaluer (il est nécessaire que toutes les expr i soient de même type, qui est aussi le type de toute l expression encadrée). Si la valeur de l expression expr est filtrée par le premier motif (càd : si elle lui correspond), alors la valeur de l expression complète (càd : celle qui est encadrée ci-dessus) sera celle de expr 1. Sinon, le motif suivant est essayé et ainsi de suite : le premier motif qui convient (c est-à-dire, qui est plus général que la valeur filtrée) est sélectionné. OCaml est capable de détecter que les cas envisagés ne couvrent pas l ensemble de toutes les éventualités; un warning (mise en garde...) est alors emis ( Warning : this pattern-matching is not exhaustive. ) à la compilation. Si la valeur n est filtrée par aucun motif, une erreur se produit (Match Failure) à l exécution. Pour que ceci n arrive pas, on peut utiliser le joker _, motif universel, qui signifie et pour tout autre motif. Examinons à présent quelques exemples : 1.1. Une fonction définie cas par cas. let f n = if n = 0 then 1 else if n = 1 or n = 2 then 5 else if n = 3 then 10 else 20 est sans doute plus pénible à écrire (et à lire!) que : let f n = match n with 0 -> 1 1 2 -> 5 3 -> 10 _ -> 20 qui peut à son tour s écrire plus simplement (noter que l argument de f n est plus explicité! Il est filtré ) : let f = function 0 -> 1 1 2 -> 5 3 -> 10 _ -> 20

2 OCAML - 3 / FILTRAGE / POLYMORPHISME / EXCEPTIONS 1.2. La fonction factorielle. On a déjà eu l occasion de la définir ainsi : let rec fact n = if n = 0 then 1 else n * fact (n-1) val fact : int -> int = <fun> Voici une version avec filtrage : let rec fact n = match n with 0 -> 1 _ -> n * fact (n-1) val fact : int -> int = <fun> ou encore, syntaxiquement plus léger : let rec fact = function 0 -> 1 n -> n * fact (n-1) val fact : int -> int = <fun> 1.3. L implication. let implique p q = (not p) q val implique : bool -> bool -> bool = <fun> La fonction implique peut aussi être définie comme suit (d après sa table de vérité) : let implique p q = match (p,q) with true, true -> true true, false -> false false, true -> true false, false -> true val implique : bool -> bool -> bool = <fun> que l on peut réduire à : let implique p q = match (p,q) with true, false -> false _ -> true val implique : bool -> bool -> bool = <fun> Remarque. La définition d une fonction à l aide du mot-clef function autorise le pattern matching, mais sans currifycation (autrement dit : avec un seul argument, dont la valeur est filtrée; voir le troisième exemple à la section 1.2 ci-dessus). A l inverse, l emploi du mot-clef fun autorise la curryfication, mais sans pattern matching. Par exemple, la construction suivante est incorrecte : let implique = fun true false -> false _ -> true true false -> false ^ Error: Syntax error On s en sort en effectuant un filtrage sur un couple (ou, plus généralement, un multiplet) : voit l exemple qui précède cette remarque.

OCAML - 3 / FILTRAGE / POLYMORPHISME / EXCEPTIONS 3 1.4. Jeu de cartes. Ce qui suit utilise la notion de type somme (qui sera présentée dans un document ultérieur) : type couleur = Pique Coeur Carreau Trefle type carte = As of couleur Roi of couleur Dame of couleur Valet of couleur Petite_carte of int * couleur let valeur couleur_atout = function As _ -> 11 Roi _ -> 4 Dame _ -> 3 Valet c -> if c = couleur_atout then 20 else 2 Petite_carte (10, _) -> 10 Petite_carte (9, c) -> if c = couleur_atout then 14 else 0 _ -> 0 val valeur : couleur -> carte -> int = <fun> valeur Pique (Valet Trefle) - : int = 2 valeur Pique (Valet Pique) - : int = 20 1.5. Filtrage d intervalles de caractères. OCaml autorise la syntaxe abrégée c 1..c n pour un motif du type c 1 c 2... c n (où les c i sont des caractères consécutifs du code ASCII) : let categorie = function a e i o u y A E I O U Y -> "voyelle" a.. z A.. Z -> "consonne" 0.. 9 -> "chiffre" _ -> "autre" val categorie : char -> string = <fun> Evidemment, il y a parmi les lettres de a à z autre chose que des consonnes, mais rappelons que lors d un filtrage par motif, le premier motif qui convient est retenu. Ceci explique le bon fonctionnement de cet exemple. categorie A - : string = "voyelle" categorie t - : string = "consonne" categorie 6 - : string = "chiffre" categorie é - : string = "autre"

4 OCAML - 3 / FILTRAGE / POLYMORPHISME / EXCEPTIONS 1.6. Filtrage avec gardes. OCaml permet d agrémenter un motif de filtrage d une condition booléenne faisant intervenir les variables du motif : 2 1 K2 K1 0 1 2 let f = function x when x >= 1. -> 1. x when x >= 0. -> x _ -> 0. K1 K2 Autre exemple : let g = function (x,0) -> 0 (0,y) -> 0 (x,y) when x < y -> x _ -> 1 val g : int * int -> int = <fun> Remarque. Pour des raisons de clarté, on évitera toutefois le filtrage avec gardes. A n employer que si on ne voit vraiment pas comment s en sortir autrement. 1.7. Un motif ne peut contenir deux fois la même variable! let f a b = match (a, b) with 0, 0 -> 0 x, x -> 1 _ -> 2 Toplevel input: > x x -> 1 > ^ Error: Variable x is bound several times in this matching On peut s en sortir en utilisant un filtrage avec garde : let f a b = match (a, b) with 0, 0 -> 0 x, y when x = y -> 1 _ -> 2 val f : int -> int -> int = <fun> f 0 0 - : int = 0 f 4 4 - : int = 1 f 4 5 - : int = 2

1.8. D autres syntaxes pour le filtrage. OCAML - 3 / FILTRAGE / POLYMORPHISME / EXCEPTIONS 5 (1) La construction let... in..., que l on a déjà rencontrée, utilise aussi le filtrage : let x = 3 in 2*x - : int = 6 Dans cet exemple, le motif x filtre la valeur 3 puis l identificateur x est liée à 3. let (x,y,_) = (10,20,50) in x + y - : int = 30 Cette fois, le motif (x,y,_) filtre la valeur (10,20,50), puis les identificateurs x et y sont respectivement liées à 10 et 20 (et la valeur 50 est perdue...). (2) Les motifs alias : let f = function (0,_,_) as m -> m (_,_,z) -> (z,z,z) val f : int * int * int -> int * int * int = <fun> La construction motif as nom permet d éviter d avoir à réécrire toute une expression en la nommant globalement. Autre exemple : let g = function ((0,0), ((_,_) as m)) -> m (((_,_) as m), (0,0)) -> m (((x,y) as m), ((x,y ) as m )) -> if x < x then m else m val g : (int * int) * (int * int) -> int * int = <fun> (3) Enfin, le rattrapage d exceptions (voir section 3 ci-dessous) utilise aussi le filtrage. 2. Polymorphisme Lorsque OCaml calcule le type d une expression (par exemple une fonction), c est le type le plus général possible qui est adopté. Ceci permet notamment de définir des fonctions agissant sur des données de types variés. Par exemple, on pourra écrire une fonction qui trie un vecteur, qu il s agisse d un vecteur d entiers ou de flottants 1. Ainsi, OCaml autorise certains types à rester indéterminés : c est un langage polymorphe. On a déjà rencontré des fonctions polymorphes : fst et snd, Array.length,... D autres exemples seront rencontrés à l occasion de l étude des listes (cf. poly 5). 2.1. La fonction identité générique. let id x = x val id : a -> a = <fun> id 19 - : int = 19 id "hop" - : string = "hop" Le type de l argument x est a (lire α), c est-à-dire n importe quel type! On dit que id est une fonction polymorphe et que a est une variable de type. 1.... ou de n importe quoi d autre, pourvu qu on dispose d une fonction de comparaison appropriée.

6 OCAML - 3 / FILTRAGE / POLYMORPHISME / EXCEPTIONS 2.2. Les fonctions fst et snd. On a déjà rencontré ces deux fonctions prédéfinies dans un document antérieur. Voici la signature de fst : fst - : a * b -> a = <fun> On pourrait les redéfinir ainsi : ou encore : let fst (x,y) = x and snd (x,y) = y val fst : a * b -> a = <fun> val snd : a * b -> b = <fun> let fst (x,_) = x and snd (_,y) = y val fst : a * b -> a = <fun> val snd : a * b -> b = <fun> Dans le même esprit, voici comment définir les fonctions de sélection des composantes d un triplet : let premier (x,_,_) = x and second (_,x,_) = x and troisieme (_,_,x) = x val premier : a * b * c -> a = <fun> val second : a * b * c -> b = <fun> val troisieme : a * b * c -> c = <fun> premier (1,10,100) - : int = 1 second (1,10,100) - : int = 10 troisieme (1,10,100) - : int = 100 2.3. Echange de deux composantes d un vecteur. let echange v a b = let tmp = v.(a) in v.(a) <- v.(b); v.(b) <- tmp val echange : a array -> int -> int -> unit = <fun> Le vecteur v est de type a array : il s agit d un type paramétré. La fonction echange peut ainsi s appliquer à des vecteurs de divers types : let v = [ 1;4;7 ] val v : int array = [ 1; 4; 7 ] echange v 0 1 - : unit = () v - : int array = [ 4; 1; 7 ] let w = [ "Pierre";"est le frère de";"paul" ] in echange w 0 2; w - : string array = [ "Paul"; "est le frère de"; "Pierre" ]

OCAML - 3 / FILTRAGE / POLYMORPHISME / EXCEPTIONS 7 2.4. La loi o. La composition des fonctions est tout naturellement une fonctionnelle (cf. poly 0) : let compose f g x = f (g x) val compose : ( a -> b) -> ( c -> a) -> c -> b = <fun> OCaml laisse indéterminés les types des arguments de f et de g mais impose une condition compatibilité : le type de l argument de f est celui de la valeur de retour de g. Si l on veut disposer d un opérateur binaire de composition des fonctions, il suffit lui choisir un nom commençant par l un des caractères suivants : = @ ^ & + - * / $ % et éventuellement suivi d un (ou plusieurs) caractère(s) choisi(s) parmi @ ^ & + - * / $ % ~!. :? et de parenthéser son nom dans la définition. Par exemple : let (@@) f g x = f (g x) val ( @@ ) : ( a -> b) -> ( c -> a) -> c -> b = <fun> Il ne reste plus qu à essayer : let u x = x + 1 u : int -> int = <fun> let v x = x * x v : int -> int = <fun> let uv = u @@ v uv : int -> int = <fun> let vu = v @@ u vu : int -> int = <fun> (uv 5, vu 5) - : int * int = (26, 36) 2.5. Tri à bulles d un vecteur. L idée du tri à bulles (en anglais : bubble sort ) est de faire remonter les éléments les plus légers vers la surface... Lorsque le vecteur à trier est de longueur 1, il n y a rien à faire! Pour un vecteur de longueur n 2, on le parcourt de gauche à droite en échangeant deux éléments consécutifs v.(i) et v.(i+1) chaque fois que v.(i) est plus grand que v.(i+1). A l issue de ce parcours, l élément le plus grand se trouve bien placé, dans la case la plus à droite. Il ne reste plus qu à refaire la même chose avec le sous-vecteur v.(0..n-2). Voila pour le principe. Passons à l implémentation... Dans un premier temps, nous comparerons deux éléments à l aide de l opérateur binaire < (qui est un opérateur polymorphe : on pourra déjà trier des vecteurs d entiers, de flottants, de caractères ou de chaines de caractères). Une version plus générale sera envisagée ensuite. L échange de deux éléments d un vecteur se fera au moyen de la fonction echange, décrite à la section 2.3 ci-dessus.

8 OCAML - 3 / FILTRAGE / POLYMORPHISME / EXCEPTIONS let tri_bulles v = let rec tri n = if n >= 2 then ( for i = 0 to n - 2 do if v.(i) > v.(i + 1) then echange v i (i + 1) done; (* le plus grand élément est maintenant à sa place *) tri (n-1); (* on recommence avec le sous-vecteur v(0..n-2) *) ) else v in tri (Array.length v) tri_bulles : a array -> a array = <fun> Passons aux essais : let v = Array.make 10 0 v : int array = [ 0; 0; 0; 0; 0; 0; 0; 0; 0; 0 ] for i = 0 to 9 do v.(i) <- Random.int (100) done - : unit = () v - : int array = [ 20; 73; 50; 61; 76; 17; 51; 62; 55; 36 ] tri_bulles v - : int array = [ 17; 20; 36; 50; 51; 55; 61; 62; 73; 76 ] Deux autres exemples (pour souligner la nature polymorphe de tri_bulles) : tri_bulles [ -1.23;-2.;3.14;-1.618;1.732;1.414 ] - : float array = [ -2.0; -1.618; -1.23; 1.414; 1.732; 3.14 ] tri_bulles [ "la";"vie";"est";"une";"fête" ] - : string array = [ "est"; "fête"; "la"; "une"; "vie" ] Venons-en à la version plus générale annoncée plus haut : il s agit de trier un vecteur dont les éléments sont de type arbitraire. Pour cela, il faut bien sûr disposer d une fonction de comparaison entre deux valeurs. La fonction tri_bulles précédente est modifiée de façon mineure : on lui passe un paramètre supplémentaire pgq (pour plus grand que ) qui est une fonction de type a -> a -> bool. Ce qui a changé est souligné : let tri_bulles_gene v pgq = let rec tri n = if n >= 2 then ( for i = 0 to n-2 do if pgq v.(i) v.(i+1) then echange v i (i+1) done; tri (n-1); ) else v in tri (Array.length v) tri_bulles_gene : a array -> ( a -> a -> bool) -> a array = <fun> A titre d exemple, trions un vecteur de chaines de caractères, en considérant qu une chaine s1 est supérieure à une chaine s2 si, et seulement si, la longueur de s1 dépasse strictement celle de s2 :

OCAML - 3 / FILTRAGE / POLYMORPHISME / EXCEPTIONS 9 let pgq s1 s2 = (String.length s1 > String.length s2) in tri_bulles_gene [ "Le";"capitaine";"Haddock";"a";"soif" ] pgq - : string array = [ "a"; "Le"; "soif"; "Haddock"; "capitaine" ] 3. Exceptions 3.1. De quoi s agit-il? L évaluation d une expression peut parfois échouer en raison d une circonstance particulière... 1 / 0 Exception: Division_by_zero let v = [ 0; 1; 2; 3; 4 ] in v.(5) Exception: Invalid_argument "index out of bounds". let s = "CAML" in s.[9] Exception: Invalid_argument "index out of bounds". List.hd [] Exception: Failure "hd". Pour comprendre le dernier exemple ci-dessus, voir le polycope n 5 (consacré aux listes). OCaml intègre un mécanisme permettant de produire (on dit aussi lever, ou raise en anglais) et d intercepter (on dit aussi rattraper, ou catch en anglais) des exceptions. L idée est la suivante : lorsqu une exception se produit, le calcul en cours est interrompu et l exception est propagée jusqu à ce qu elle soit éventuellement rattrapée, c est-à-dire gérée proprement, en quelque sorte. En cas d exception non rattrapée ( uncaught exception ), un message d erreur est affiché (comme dans les trois exemples ci-dessus). Les exceptions appartiennent à un type spécial (le type exn), qui comporte des constantes prédéfinies parmi lesquelles : Division_by_zero - : exn = Division_by_zero Out_of_memory - : exn = Out_of_memory Le type exn est extensible, au sens où le programmeur peut définir ses propres exceptions : exception Nombre_trop_grand (* Attention : la majuscule compte! *) exception Nombre_trop_grand Le constructeur Failure permet de générer une exception à l aide d un paramètre de type string : Failure catastrophe - : exn = Failure catastrophe 3.2. Comment lever une exception? La fonction raise effectue cette tâche : raise - : exn -> a = <fun> La fonction failwith permet une syntaxe simplifiée. Par exemple, l expression équivaut à failwith catastrophe

10 OCAML - 3 / FILTRAGE / POLYMORPHISME / EXCEPTIONS raise (Failure catastrophe ) On aura noté que la fonction raise renvoie un type polymorphe : cela lui permet de s adapter à tous les contextes, comme le montrent les deux exemples suivants. let f = function 0. -> failwith "0 interdit" 1. -> failwith "1 interdit" x -> 1. /. (x *. (1. -. x)) f : float -> float = <fun> let rpo x v = (* Rang de la Première Occurrence de la valeur x dans le vecteur v *) let i = ref 0 and found = ref false and n = Array.length v in while (not!found) && (!i < n) do if v.(!i) = x then found := true else incr i done; if!i = n then failwith "Not found" else!i rpo : a -> a array -> int = <fun> Dans le premier de ces deux exemples, il FAUT que l expression failwith "0 : valeur interdite" soit de type float. Dans le second, il FAUT que l expression failwith "Not found" soit de type int. 3.3. Comment rattraper une exception? Avec la construction try... with... dont la syntaxe est la suivante : try e with m 1 -> e 1... m r -> e r Les m i sont des motifs de type exn et les e i sont des expressions ayant toutes le même type, à savoir celui de e. Si l évaluation de e ne déclenche pas d exception, la valeur de l ensemble de l expression est celle de e. Si en revanche une exception se produit, alors les motifs sont essayés l un après l autre : dès que l un d eux disons m i filtre cette exception, c est la valeur de e i qui est retenue. Prenons l exemple de la fonction f définie à la section précédente : f n est définie ni en 0 ni en 1, mais la fonction : f : x 1 x (1 x) g : x sin (2x) sin (3 (1 x)) f (x) est prolongeable par continuité en 0 et en 1 et les valeurs de prolongement sont respectivement 2 sin (3) et 3 sin (2). Voici comment on peut définir g en OCaml : let g x = try sin(2. *. x) *. sin (3. *. (1. -. x)) *. f(x) with Failure "0 interdit" -> 2. *. sin(3.) Failure "1 interdit" -> 3. *. sin(2.) g : float -> float = <fun>

OCAML - 3 / FILTRAGE / POLYMORPHISME / EXCEPTIONS 11 Considérons maintenant l exemple de la fonction rpo définie à la section précédente et définissons une fonction subs telle que subs src v r effectue le remplacement de la première occurrence dans v de chaque terme de src par r : let subs src v r = let n = Array.length src in for i = 0 to n-1 do v.(rpo src.(i) v) <- r done; v subs : a array -> a array -> a -> a array = <fun> subs [ 1;2;3 ] [ 5;3;1;3;6;1;2 ] 0 - : int array = [ 5; 0; 0; 3; 6; 1; 0 ] subs [ 1;2;7 ] [ 5;3;1;3;6;1;2 ] 0 Uncaught exception: Failure "Not found" Pour rattraper le coup, on modifie comme suit la fonction subs : let subs src v r = let n = Array.length src in for i = 0 to n-1 do try v.(rpo src.(i) v) <- r with Failure "Not found" -> () done; v subs : a array -> a array -> a -> a array = <fun> subs [ 1;2;7 ] [ 5;3;1;3;6;1;2 ] 0 - : int array = [ 5;3;0;3;6;1;0 ] 0 Dans un document ultérieur, on verra comment le calcul du déterminant d une matrice carrée peut être programmé en utilisant une exception pour gérer le cas des matrices non inversibles.