Programmation fonctionnelle

publicité
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
Téléchargement