22/03/2017 CC1 Répartition des notes Programmation fonctionnelle 40 35 30 25 Cours 10 : type somme les enregistrements Licence 1 Année 2016 – 2017 20 15 10 5 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Par N. VINCENT Les couleurs Définition récursive du type On peut vérifier qu'une couleur est une couleur primaire # let primaire x = match x with | Bleu | Vert | Rouge -> true | _ -> false ;; val primaire : t_couleur -> bool = <fun> # primaire Vert ;; - : bool = true # primaire v ;; - : bool = false # primaire Bleu ;; - : bool = true # primaire Rouge ;; - : bool = true # primaire (Numero 3) ;; - : bool = false # type t_couleur = | Bleu | Vert | Rouge | Numero of int | Melange of t_couleur * t_couleur ;; type t_couleur = Bleu Les constructeurs sont Bleu, | Vert Vert, Rouge, Numero, Melange | Rouge | Numero of int | Melange of t_couleur * t_couleur # let c1 = Melange (Bleu , Rouge) ;; val c1 : t_couleur = Melange (Bleu, Rouge) # primaire 3 ;; # let c2 = Melange (Bleu , Numero 3) ;; val c2 : t_couleur = Melange (Bleu, Numero 3) Error: This expression has type int but an expression was expected of type couleur # primaire Numero 3 ;; # let v = Numero 3 ;; Error: This function is applied to too many arguments; val v : t_couleur = Numero 3 you forgot fonctionnelle a `;' Licencemaybe 1 - programmation 3 # let c3 = Melange (c2 , Bleu) ;; val c3 : t_couleur = Melange (Melange (Bleu, Numero 3), Bleu) Licence 1 - programmation fonctionnelle Exemple Exemple Compter le nombre de couleurs bleu dans une liste Une peinture contient-elle du bleu ? # let rec avecbleu c = match c with | Bleu -> true | Melange (m1,m2) -> avecbleu m1 || avecbleu m2 | _ -> false ;; val avecbleu : t_couleur -> bool = <fun> # let rec compte l x = match l with | [] -> 0 | h::t -> if h = x then 1 + (compte t x) else compte t x ;; val compte : 'a list -> 'a -> int = <fun> # let ll = [Bleu ; Vert ; Vert ; Bleu ; Rouge ] ;; val ll : t_couleur list = [Bleu; Vert; Vert; Bleu; Rouge] # avecbleu c1 ;; - : bool = true # compte ll Bleu ;; - : int = 2 # avecbleu c2 ;; - : bool = true # let lc=[Bleu; Vert; Vert; Numero 3; Bleu; Melange (Bleu , Vert); Rouge ] ;; val lc : t_couleur list = # let c4 = Melange (c2 , Rouge) ;; val c4 : t_couleur = Melange (Melange (Bleu, Numero 3), Rouge) # avecbleu c4 ;; - : bool = true 4 [Bleu; Vert; Vert; Numero 3; Bleu; Melange (Bleu, Vert); Rouge] # compte lc Bleu ;; Licence 1 - programmation fonctionnelle 5 - : int = 2 Licence 1 - programmation fonctionnelle 6 1 22/03/2017 Exemple Version terminale Compter le nombre de couleurs contenant du bleu dans une liste Compter le nombre de couleurs contenant du bleu dans une liste # let rec compte1 l = match l with | [] -> 0 | h::t -> if avecbleu h then 1 + (compte1 t ) else compte1 t ;; # let rec f acc l = match l with | [] -> acc | h::t -> if avecbleu h then (f (acc+1) t ) else f acc t ;; val compte1 : t_couleur list -> int = <fun> val f : int -> t_couleur list -> int = <fun> # f 0 lc ;; - : int = 3 # compte ll Bleu ;; - : int = 2 # let lc=[Bleu; Vert; Vert; Numero 3; Bleu; Melange (Bleu , Vert); Rouge ] ;; val lc : t_couleur list = [Bleu; Vert; Vert; Numero 3; Bleu; Melange (Bleu, Vert); Rouge] # let nomb l = let rec f acc ll = match ll with | [] -> acc | h::t -> if avecbleu h then (f (acc+1) t ) else f acc t in f 0 l ;; val nomb : t_couleur list -> int = <fun> # compte1 lc ;; # nomb lc ;; - : int = 3 7 Licence 1 - programmation fonctionnelle - : int = 3 Licence 1 - programmation fonctionnelle Type somme : exemple Nature d’une variable Peut on savoir de quel cas relève une valeur ? # type t_longueur = Metre of float | Pied of float ;; type t_longueur = Metre of float | Pied of float # type t_longueur = Metre of float | Pied of float ;; type t_longueur = Metre of float | Pied of float On ne peut pas additionner des énumérés # Metre 3. +. Metre 5. ;; Error: This expression has type t_longueur # let metre x = match x with |Pied y -> false | _ -> true;; but an expression was expected of type float val metre : t_longueur -> bool = <fun> Comment atteindre les réels 3 et 5 ? # let v = Metre 3. ;; # metre Pied 4. ;; Error: This function is applied to too many # metre v ;; - : bool = true arguments; maybe you forgot a `;' # let v = Metre 3. ;; # let valeur x = match x with Metre y -> y | Pied y -> y ;; val valeur : t_longueur -> float = <fun> 8 # valeur v ;; - : float = 3. Licence 1 - programmation fonctionnelle 9 Opérations # metre (Pied 4.) ;; - : bool = false Licence 1 - programmation fonctionnelle 10 Opérations conversion Additionner des éléments de type longueur # let rec addadd x y x=ymatch (x,y) withwith | (Metre z , Metre r) -> = match (x,y) | (Metre z , Metre r) -> Metre ( z +. r) | (Pied z , Pied r) -> conversion (Pied (z+. r)) # type t_longueur = Metre of float | Pied of float ;; type t_longueur = Metre of float | Pied of float | (Metre z , Pied r) -> add x (conversion y) | (Pied z , Metre r) -> add ;; (conversion x) y ;; # let conversion x = match x with |Pied y -> Metre ( 0.30 *. y) | Metre y -> Pied (y /. 0.30) ;; val add : t_longueur -> t_longueur -> t_longueur = <fun> # add (Metre 5.) (Metre 8.) ;; - : t_longueur = Metre 13. val conversion : t_longueur -> t_longueur = <fun> # conversion (Metre 1.) ;; # add (Pied 5.) (Pied 8.) ;; - : t_longueur = Pied 3.33333333333333348 - : t_longueur = Metre 3.9 # conversion (Pied 12.) ;; # add (Metre 5.) (Pied 3.) ;; - : t_longueur = Metre 3.59999999999999964 Licence 1 - programmation fonctionnelle - : t_longueur = Metre 5.9 11 # add (Pied 3.) (Metre 5.) ;; - :Licence t_longueur = Metre 5.9 1 - programmation fonctionnelle 12 2 22/03/2017 Type nombre Type nombre On peut définir un type compatible réel et entier # type t_nombre = Reel of float | Entier of int ;; type t_nombre = Reel of float | Entier of int # type t_nombre = Reel of float | Entier of int ;; type t_nombre = Reel of float | Entier of int On doit définir des opérations # let v1 = Entier 5 and v2 = Entier (-3) and v3 = Reel 4. and v4 = Reel 2.5 ;; val v1 : t_nombre = Entier 5 val v2 : t_nombre = Entier (-3) somme # let somme x y = match (x,y) with | (Reel x1 , Reel x2) -> Reel (x1 +. x2) | (Reel x1 , Entier x2) -> Reel (x1 +. float_of_int (x2)) | (Entier x1 , Entier x2) -> Entier (x1 + x2) | (Entier x1 , Reel x2) -> Reel (float_of_int(x1) +. x2) ;; val v3 : t_nombre = Reel 4. val somme : t_nombre -> t_nombre -> t_nombre = <fun> val v4 : t_nombre = Reel 2.5 # let v1 = Entier 5 and v2 = Entier (-3) and v3 = Reel 4. and v4 = Reel 2.5 ;; Ils ont tous le même type Mais aucun opérateur n’est prévu Licence 1 - programmation fonctionnelle 13 Exercice 2-1 # somme v1 v2 ;; - : t_nombre = Entier 2 # somme v1 v3 ;; - : t_nombre = Reel 9. Licence 1 - programmation fonctionnelle Exercice 2-2 Une liste contient une série temporelle de mesures qui sont soit des mesures de température, soit des mesures de hauteur. Ses éléments sont de type t_mesure défini par :Type t_mesure = |Temp of int |Haut of int ;; # somme v3 v4 ;; - : t_nombre = Reel 6.5 # somme v4 v2 ;; - : t_nombre = Reel (-0.5) 14 Type t_mesure = |Temp of int |Haut of int ;; 2°/Ecrire une fonction fcompte qui à partir d’une liste de mesures de type t_mesure, calcule un couple contenant respectivement les nombres de mesures des températures et des hauteurs contenues dans la liste de mesures. 1°/ Ecrire une fonction add qui calcule terme à terme la somme de deux couples d’entiers. # let x = [Temp 3 ; Temp 2 ; Haut 2 ; Temp 2 ; Haut 4] ;; val x : t_mesure list = [Temp 3; Temp 2; Haut 2; Temp 2; Haut 4] # let rec fcompte l = match l with [] -> (0,0) | (Temp x) :: t -> add (fcompte t) (1,0) | (Haut x) :: t -> add (fcompte t) (0,1) ;; val fcompte : t_mesure list -> int * int = <fun> # let add (x,y) (z,t) = (x+z , y+t) ;; val add : int * int -> int * int -> int * int = <fun> # add (5,4) (0,1) ;; - : int * int = (5, 5) # fcompte x ;; - : int * int = (3, 2) Licence 1 - programmation fonctionnelle Exercice 2-3 15 Type t_mesure = |Temp of int |Haut of int ;; 3°/ Ecrire une fonction fmoy qui à partir d’une liste de mesures de type t_mesure, calcule un couple contenant respectivement les moyennes des températures et des hauteurs contenues dans la liste de mesures. # let fmoy l = let rec fsom ll = match ll with [] -> (0,0) | (Temp x) :: t -> add (fsom t) (x,0) | (Haut x) :: t -> add (fsom t) (0,x) in let (n1,n2) = fcompte l in let (s1,s2) = fsom l in (float_of_int s1) /. (float_of_int n1) , (float_of_int s2) /. (float_of_int n2) ;; val fmoy : t_mesure list -> float * float = <fun> Licence 1 - programmation fonctionnelle Exercice 2-4 16 Type t_mesure = |Temp of int |Haut of int ;; 4°/ Ecrire une fonction fmax qui à partir d’une liste de mesures de type t_mesure, calcule un couple contenant respectivement les valeurs maximum des températures et des hauteurs contenues dans la liste de mesures. On vérifiera que la liste comporte au moins une mesure de hauteur et une mesure de température, sinon une exception indiquera ce cas. let fmax l = let (n1,n2) = fcompte l in if n2<1 && n1<1 then invalid_arg "pas de measures" else let rec ft ll = match ll with | (Temp x) :: t -> x | (Haut x) :: t -> ft t | [ ] -> 0 in let rec fh ll = match ll with | (Temp x) :: t -> fh t val fmax | (Haut : t_mesure x) :: t ->listx -> int * int = <fun> # let x = [Temp 3 ; Temp 2 ; Haut 2 ; Temp 2 ; Haut 4] ;; | [ ] -> 0 val x : t_mesure list = [Temp 3; Temp 2; Haut 2; Temp 2; Haut 4] in let rec ffmax acc1 acc2 ll = match ll with [Temp x] -> (max x acc1, acc2) | [Haut x] -> (acc1 , max x acc2) | (Temp x) :: t -> ffmax (max x acc1) acc2 t | (Haut x) :: t -> ffmax acc1 (max x acc2) t | [ ] -> (acc1 , acc2) in ffmax (ft l) (fh l) l ;; val fmax : t_mesure list -> int * int = <fun> # fmax x ;; # let x = [Temp 3 ; Temp 2 ; Haut 2 ; Temp 2 ; Haut 4] ;; val x : t_mesure list = [Temp 3; Temp 2; Haut 2; Temp 2; Haut 4] # fmoy x ;; - : float * float = (2.33333333333333348, 3.) Licence 1 - programmation fonctionnelle 17 - : int * int = (3, 4) Licence 1 - programmation fonctionnelle 18 3