Programmation fonctionnelle Langage Caml Licence 1

publicité
Programmation fonctionnelle
Langage Caml
Licence 1ère année
année 2016 - 2017
Recueil
de
documents de travail
Pr. Nicole VINCENT
Table des matières
cours n° 1 ................................................................................. 4
TD1 .......................................................................................... 5
cours n° 2 ................................................................................. 7
TD2 .......................................................................................... 8
cours n° 3 ................................................................................. 9
TD3 .......................................................................................... 10
cours n° 4 ................................................................................. 11
TD4 .......................................................................................... 12
cours n° 5 ................................................................................. 13
TD5 .......................................................................................... 14
cours n° 6 ................................................................................. 15
TD6 .......................................................................................... 16
cours n° 7 ................................................................................. 17
TD7 .......................................................................................... 18
cours n° 8 ................................................................................. 19
TD8 .......................................................................................... 20
cours n° 9 ................................................................................. 21
TD9 .......................................................................................... 22
cours n° 10 ............................................................................... 23
TD10 ........................................................................................ 24
cours n° 11 ............................................................................... 25
TD11 ........................................................................................ 26
cours n° 12 ............................................................................... 27
TD12 ........................................................................................ 28
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Programme du semestre
Cours n° 1
Cours : les principes généraux des types
Cours n° 2
Cours : la définition d'une fonction – n-uplet
TD et TP 1 : analyse des types
Cours n° 3
Cours : fonction argument et résultat
TD et TP 2 : construction de fonctions
Cours n° 4
Cours : fonctions et filtrage – gestion des erreurs
TD et TP 3 : fonctions
Cours n° 5
Cours : les listes
TD et TP 4 : les listes
Cours n° 6
Cours : les foncions récursives
TD et TP 5 : fonctions récursives
Cours n° 7
Cours : les fonctions récursives terminales
TD et TP 6 : fonctions récursives
Cours n° 8
Cours : types énumérés - somme
TD et TP 7 : Révisions
Cours n° 9
Cours : enregistrements
TD et TP 8: fonctions récursives
Cours n° 10
Cours : types structurés
TD et TP 9: types énumérés
Cours n° 11
Cours : modélisation de données, les polynômes
TD et TP 10: enregistrements
Cours n° 12
Cours : révisions
TD et TP 11 : révisions
Semaine
n° 13
TD12 : révisions
TP12 : CC3
3
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n°1
Le but est ici de comprendre la notion de type
les types classiques : int (5), float (5.), bool (true , false) , char (`a`), string ("Caml")
les opérateurs associés aux entiers : + , - , * , / , mod , abs
les opérateurs associés aux réels : +. , -. , *. , /. , ** , sqrt
les opérateurs de comparaison : = , <> , < , > , <= , >=
les changements de types : type1_of_type2
le type fonction : fun (x -> x + 1)
le type unit : ()
l’affectation : let x = 3
conditionnelle
if (condition) then expression1 else expression2
où expression1 et expression2 sont des expressions d’un même type, celui pris par
l’expression globale
quelques fonctions de base :
min , max
print_int , print_float , print_string , print_newline
un programme est une suite d’expressions
Le langage est interprété.
Une expression est calculée après les symboles ;;
Exemple :
Décrire une valeur par une expression dépendant d’un entier x et dont la valeur est un booléen
indiquant si l'entier est pair ou non
# let x = 24 ;;
val x : int = 24
# let a = x mod 2 = 0 ;;
val a : bool = true
4
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser – TD1
Exercice 1
Pour chacune des expressions suivantes, indiquer son type et sa valeur. Si l'expression est mal
écrite on devra proposer une écriture exacte
3 + 6 ;;
3 +. 6 ;;
3 + 6. ;;
3 +. 6. ;;
3. +. 6. <= 9 ;;
x = 3 + 4 ;;
“a” > ‘b’ ;;
let x = “bonjour” ;;
let x = 2 = 1 ;;
let x = ‘c’ in x = ‘a’ ;;
let x = ‘c’ = “a” ;;
not 'z' > 'a' && 2 = 2 ;;
char_of_int (int_of_char ‘c’ + 2 ) ;;
int_of_string "142" + -73 ;;
let b = true in if b then "oui" else "non" ;;
let p=true and q=true in if p & q then false else true ;;
x = 2 ;; 3 + 4 ;;
( ) ; 3 + 4 ;;
Exercice 2
Calculer :
- la racine carrée de 4
- la puissance 3 de 5 : 53
- le minimum entre 3 et 10
- le minimum entre 3 et 1.5
- le minimum entre 1/2 et 1/3
Remarque : il existe une fonction qui permet de calculer le minimum entre deux nombres de
même type : min x y
Exercice 3
Ecrire une expression dont la valeur est égale à la somme des n premiers entiers positifs.
!
L’expression est : ! !(! + 1)
Exercice 4
1°/Ecrire une expression dont la valeur est égale à 75 pour cent d’une valeur réelle qui sera
notée x.
2°/ Ecrire une expression dont la valeur est égale à a pour cent d’une valeur réelle qui sera
notée x.
3°/ Ecrire une suite d’expressions permettant en utilisant l’expression de la seconde question
et dont la valeur est égale à 65% de 120.
5
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Exercice 5
1°/ Affecter à une constante nommée a, un booléen indiquant si un entier x qui aura été
affecté auparavant est supérieur à 80.
Exécuter pour différentes valeurs de x : 67 , -45 , 184 ;
2°/ Affecter à une constante nommée b, un booléen indiquant si un entier x qui aura été
affecté auparavant est compris entre 60 et 120.
Exécuter pour différentes valeurs de x : 67 , -45 , 184 ;
3°/ Ecrire une expression utilisant une variable booléenne et qui imprime vrai si l'argument est
vrai, imprime faux si l'argument est faux.
On observera l'interprétation des types qui est faite.
Evaluer l’expression pour les valeurs suivantes de la variable : true, false, 3=3 , 3=2
Exercice 6
1°/ Indiquer les types des constantes notées par des lettres, ainsi que le type des résultats.
if (x mod 2) = 0 then (5 + (x / 2)) else (2 * x)
if (x < 0) && (y > sqrt(2.)) then y else x
2°/ Expérimenter chaque expression pour des valeurs particulières
6
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n°2
Le but est ici d'assimiler la notion de fonction.
Définition d'une fonction en affectant une variable f à l’aide de let
Par la valeur du résultat
let f x = x + 1
par la définition de la transformation de l’argument en résultat
let f = fun x -> x + 1
Les arguments d’une fonction sont séparés par un espace
let f x y = x * y
Appel d’une fonction f x
fxyz
Le type n-uplet avec le constructeur , : il permet de regrouper dans une variable plusieurs
éléments ayant des types variés
# let x = ("caml" , 18) ;;
val x : string * int = ("caml", 18)
Exemples :
Ecrire une fonction ayant pour arguments 2 couples comprenant chacun un entier et un réel et
dont le résultat est la somme des produits terme à terme des éléments.
# let f (x1,x2) (y1,y2) = x1 *. y1 +. float_of_int (x2 * y2) ;;
val f : float * int -> float * int -> float = <fun>
# f(3.,3)(1.,5) ;;
- : float = 18.
Ecrire une fonction ayant pour arguments 2 couples, chaque couple comporte un booléen et
un réel. Le résultat est un couple de même nature. Quand les booléens des arguments sont
égaux le booléen résultat est vrai et le réel est la somme des réels et quand les booléens sont
différents, le booléen du résultat est faux et le réel est le produit des réels.
# let f (x1,x2) (y1,y2) = let test = (x1 = y1) in if test then ( test , x2 +. y2)
else ( test , x2 *. y2) ;;
val f : 'a * float -> 'a * float -> bool * float = <fun>
# f (true , 4.5) (2=2 , 5.7) ;;
- : bool * float = (true, 10.2)
# f (true , 4.5) ( (2=1) , 5.7) ;;
- : bool * float = (false, 25.6500000000000021)
Remarque : Il n’est pas nécessaire que le premier élément des arguments soit un booléen, la
seule chose est que les premiers éléments des arguments soient de même type.
f (1.2, 4.5) (1.2 , 1.8) ;;
7
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser – TD2
Exercice 1
Etant donnée la définition : f (x,y) = (x+y , x*y), indiquer le type et la valeur des expressions
suivantes, (éventuellement les erreurs de syntaxe peuvent être détectées et corrigées),
- f 3 , 2 ;;
- f (f(3,2)) ;;
- f f(3,2) ;;
- f(3. , 2.)
- f(3.,2) ;;
- f ( -3 , 2) ;;
- f -3 , 2 ;;
- let z = -3 , 2 ;; f z ;;
Exercice 2
En transformant les expressions écrites la semaine dernière en fonctions, écrire une fonction
qui imprime vrai ou faux en fonction de l'appartenance de la variable entière à l'intervalle [60
, 120]
Exécuter la fonction pour les arguments -32 , 3 , 78
Exercice 3
1°/ Ecrire l'addition comme une fonction de deux arguments puis comme une fonction d'un
seul argument.
2°/ Ecrire une fonction qui calcule le plus petit entier pair, supérieur ou égal à la somme de
deux entiers, arguments de la fonction.
Exercice 4
Ecrire une fonction f de deux arguments qui retourne le plus grand de deux arguments.
En utilisant la fonction précédente écrire une fonction g ayant 3 arguments et qui retourne la
plus grande des trois valeurs.
Exercice 5
Ecrire une fonction qui donne le nombre de chiffres d'un entier écrit en base 10.
Exercice 6
Ecrire une fonction booléenne qui permet de vérifier qu'un point connu par un couple de
coordonnées dans un repère (O;i,j), appartient à une droite d'équation ax+by+c=0. La droite
est connue par les trois valeurs a b et c.
On précisera le nombre d'arguments de la fonction.
On écrira l'appel à la fonction pour le point de coordonnées (0,5 ; 2) et la droite d'équation
x+y=0
8
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n°3
Le but est ici d’approfondir la notion de fonction.
L’usage des types indéterminés
Les fonctions comme argument
Les fonctions comme résultat
Une fonction peut être définie localement dans un calcul ou dans la définition d’une autre
fonction
let puis4 x = let carre x = x * x in carre(carre x) ;;
Un ensemble d’expressions peuvent être réunies dans un bloc begin … end
Le type de l’expression globale est celui de la dernière expression
La définition d’une variable (qui peut être une fonction) peut être introduite localement par in
Exemples :
L’argument d’une fonction peut être une fonction
# let f g x = 3 + g x ;;
val f : ('a -> int) -> 'a -> int = <fun>
# let g x = x * x ;;
# let h x = x * x ;;
# let hh z = z + 1 ;;
# f h 5 ;;
- : int = 28
# f hh 6 ;;
- : int = 10
Ecrire une fonction dont l'argument est entier et qui affiche si l'entier est pair ou impair
#let parite x = if (x mod 2 = 0) then begin print_int x ; print_string " est un entier pair" ;
print_newline() end else begin print_int x ; print_string " est un entier impair" ;
print_newline() end ;;
parite : int -> unit = <fun>
# parite 354 ;;
354 est un entier pair
- : unit = ()
9
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser – TD3
Exercice 1
1°/ Indiquez l'interprétation de l’expression suivante :
# let fc a b c d = a b c + if d = (0,0) then b c else c;;
2°/Comment interpréter les évaluations suivantes et donner un exemple de code
correspondant.
a/ val f : int -> int -> 'a -> ('a -> int) -> int = <fun>
b/ val f : 'a -> ('a -> 'a) -> 'b -> ('a -> ('a -> 'a) -> 'b) -> bool = <fun>
Exercice 2
Etant donnée la définition :f g h x y z = g x y && h y z
1°/ Proposer des définitions de g et de h
2°/ Quelle est la nature de f g h ?
3° Evaluer : f (fun x y -> x > y) (fun x y -> x * x > y) 4 (-3) 5
Exercice 3
Ecrire une fonction admettant deux arguments, une fonction et une variable qui permet
d'appliquer la fonction deux fois ( fof(x) ).
Appliquer le résultat à une fonction de votre choix
Peut-on l’appliquer à la fonction de l’exercice 1 de la semaine précédente ?
Exercice 4
Ecrire une fonction dont l’argument est entier et qui retourne un booléen indiquant si l’entier
est le carré d’un entier.
Exercice 5
Ecrire une fonction dont le résultat est une fonction permettant de calculer la moyenne
pondérée de 3 valeurs. La fonction de moyenne est donc caractérisée par trois valeurs dont la
somme est égale à 1.
On proposera plusieurs solutions en utilisant ou non des n-uplets
10
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n°4
Le but est ici d’approfondir la notion de fonction et d’assimiler la notion de filtrage.
Le filtrage s’effectue sur une expression qui est comparée à différents motifs, et l’expression
finale prend différentes formes ayant toutes le même type
match expression with
motif1 -> expression1
| motif 2 -> expression2
| motif 3 -> expression3
| _
-> expression4
un motif peut être exprimé comme une valeur quelconque, tous les autres cas : _
gestion des exceptions
assert permet de préciser les valeurs valides pour une fonction : assert (n>0) ;
l’argument est un booléen
failwith permet d’indiquer une cause d’exception : failwith ″Division par zéro″
l’argument est une chaîne
peut se substituer à une expression de n’importe quel type
invalid_arg permet d’indiquer qu’un cas n’est pas pris en compte par la fonction : invalid_arg
″La liste n’a pas assez de termes″
l’argument est une chaîne
peut se substituer à une expression de n’importe quel type
Exemples :
Fonction dont l’argument est un couple d’entiers et qui le transforme en un couple où les
nombres pairs auront été divisés par 2.
# let f c = match c with (x , y ) -> match (x mod 2 , y mod 2) with | (0,0) -> (x/2 , y/2)
| (0,1) -> (x/2 , y)
| (1,0) -> (x , y/2)
| (_,_) -> (x , y) ;;
val f : int * int -> int * int = <fun>
# f (5 , 10) ;;
- : int * int = (5, 5)
11
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser – TD4
Exercice 1
Ecrire une fonction qui associe à un entier positif, 3 fois sa valeur si l’entier est multiple de 3
(il s’écrit 3n), 7 fois sa valeur si l’entier est multiple de 3 plus 1 (il s’écrit 3n+1), 21 fois sa
valeur si l’entier est un multiple par 3 plus 2 (il s’écrit 3n+2).
Exercice 2
Dans un filtrage un ensemble de valeurs consécutives dans un ensemble ordinal peut être
remplacé par un intervalle d’extrémités a et b dont la syntaxe est a .. b
1°/ Ecrire une fonction booléenne qui vérifie qu’un argument caractère est une des 26 lettres
de l’alphabet.
2°/ Ecrire une fonction dont le résultat est une chaîne indiquant si un argument caractère est
un voyelle, une consonne, un chiffre ou autre.
Exercice 3
1°/ Ecrire une fonction ttc qui calcule un prix TTC en fonction de deux arguments, le prix HT
de l’objet et sa catégorie 1, 2 ou 3 . Les pourcentages de TVA s'appliquent en fonction de la
catégorie et ont respectivement pour valeur 5% , 7% et 20%.
2°/ Ecrire l’appel à la fonction ttc pour un objet appartenant à la catégorie 3 dont le prix HT
est égal à cinquante euros.
Exercice 4
Ecrire une fonction qui à deux couples formés d’une chaîne et d’un entier associe la chaîne et
la somme des entiers si les deux chaînes en argument sont identiques et la chaine ‘différents’
et l’entier nul si les chaînes ne sont pas identiques.
Exercice 5 (second degré)
1°/ Ecrire une fonction qui calcule le nombre de racines réelles d'une équation du second
degré. La fonction aura 3 arguments réels (les 3 coefficients de l'équation et on supposera non
nul le coefficient du terme du second degré. On pourra créer des fonctions intermédiaires.
2°/ Résoudre l'équation du second degré. Le résultat sera un triplet dont le premier élément est
un entier qui indique le nombre de solutions de l'équation, les deux suivants sont les solutions
éventuelles de l'équation..
Exercice 6
1°/ On considère des triplets contenant une chaîne et deux réels. Ecrire une fonction
trans3to2 admettant x pour argument, qui transforme un tel triplet en un couple qui contient
la chaîne et la somme des deux réels.
Ainsi ( ‟caml‟, 2.4 , 5.1) est transformé en ( ‟caml‟, 7.5 )
2°/ Un couple contient une chaîne et un réel. Ecrire une fonction trans2to3 admettant un seul
argument, qui transforme un tel couple en un triplet qui contient la chaîne, le réel et un second
réel égal à la somme du premier réel et de la longueur de la chaîne.
Ainsi ( ‟caml‟, 2.4 ) est transformé en ( ‟caml‟, 2.4, 6.4 )
12
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n°5
Le but est ici d'assimiler la notion de liste.
C’est un conteneur de longueur variable dont tous les éléments ont le même type.
let l1 = [2 ; 3 ; 4]
son type est : nom_de_type list
Une liste contient un premier terme et le reste (la tête et la queue) (head and tail) h ::t
head est un élément ; tail est une liste
on peut ajouter un élément au début d’une liste : let l2 = 1 :: l1
la liste vide s’écrit : []
Fonctions utiles
List.hd extrait la tête d’une liste non vide
List.hd l
List.tl extrait la queue d’une liste non vide
List.tl l
List.length indique la longueur d’une liste
List.length l
List.append permet de concaténer 2 listes
List.append l1 l2
List.map applique une fonction à chaque élément d’une liste :
List.map f l
List.mem teste l’appartenance d’un élément à une liste
List.mem x l
List.for_all teste si une propriété de tous les éléments d’une liste List.for_all f l
List.sort trie les éléments d’une liste en fonction d’un critère de comparaison
let decroit x y = if x < y then 1 else -1
List.sort decroit l
Exemple :
# let f g h l1 l2 = if (List.for_all g l1) && (List.for_all g l2) then List.append l1 l2 else
List.append (List.map h l1) (List.map h l2) ;;
val f : ('a -> bool) -> ('a -> 'a) -> 'a list -> 'a list -> 'a list = <fun>
# let l1 = [2 ; 5 ; 76 ; 9] ;;
val l1 : int list = [2; 5; 76; 9]
# let l2 = [2 ; 76 ; 44 ; 22 ; 14] ;;
val l2 : int list = [2; 76; 44; 22; 14]
# let l3 = [68 ; 88 ; 34 ; 12] ;;
val l3 : int list = [68; 88; 34; 12]
# let gg x = x mod 2 = 0 ;;
val gg : int -> bool = <fun>
# let hh x = 2 * x ;;
val hh : int -> int = <fun>
# f gg hh l1 l2 ;;
- : int list = [4; 10; 152; 18; 4; 152; 88; 44; 28]
# f gg hh l2 l3 ;;
- : int list = [2; 76; 44; 22; 14; 68; 88; 34; 12]
13
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser – TD5
Exercice 1
Indiquer le type et la valeur des expressions suivantes, ou le commentaire de l'interpréteur
caml :
1::[2;3];;
1. ::[2 ;3] ;;
1 ::[2 ; 2<3 ; 3] ;;
1 ::[] ;;
1 ::[1 , 2 , 3] ;;
[ ] ::[[1,2,3]] ;;
[1;2]::3 ;;
[1;2]::[3] ;;
[1;[2;3]];;
[[1];[2;3]];;
‘c’ ::["aml"] ;;
(1,’a’)::[2,’c’ ; 3,’e’] ;;
Exercice2
Reprendre l’exercice (second degré) de la semaine dernière et
Résoudre l'équation du second degré. Le résultat sera une liste qui pourra avoir 0, 1 ou 2
éléments en fonction du nombre de solutions de l'équation.
Exercice 3
1°/ Ecrire une fonction qui permet de vérifier qu'une liste de caractères contient la suite des
caractères du mot caml.
2°/ Ecrire une fonction qui permet de supprimer le premier caractère d'une liste de caractères
si c'est un espace.
Exercice 4
1°/ Ecrire une fonction qui permet de rentrer en plusieurs étapes, au clavier, les éléments
d'une liste d'entiers positifs, il n'y aura aucune action quand la valeur entrée est négative.
2°/ Ecrire une fonction qui vérifie que les éléments d'une liste d'entiers ne comporte que des
entiers pairs.
3°/ Ecrire une fonction qui conserve les entiers pairs d'une liste et multiplie par 2 les entiers
impairs.
4°/ Ecrire une fonction qui trie les entiers de la liste par ordre croissant.
14
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n° 6
Le but est ici d'assimiler la notion de récursivité.
Le principe de la récursivité est de remplacer la résolution d’un problème par celle d’un
problème “plus simple” auquel il est lié alors qu’on sait traiter le cas “le plus simple”.
Une fonction récursive est une fonction qui s’appelle elle-même. Pour que cela soit possible
un mot clé lors de la définition est nécessaire
Let rec f x = …
Etapes de construction :
Principe général
Choix du cas le plus simple et
résolution
Critère de simplicité
Passage du cas général à un “cas plus
simple”
Lien entre le cas général et un “cas
plus simple”
Calcul de la longueur d’une liste l
Liste vide : de longueur nulle
Longueur de la liste à traiter
Une liste cas général (l = h ::t) est de
longueur plus longue que son reste (t)
Longueur de l = 1 + Longueur de t
#trace f et #untrace f permettent de voir la suite des appels durant le calcul et d’arrêter ce
processus.
Exemple :
let rec longueur l = if l = [] then 0 else 1 + longueur (List.tl l)
Fonction qui associe à une liste d’entiers, un couple de valeurs constitué de la moyenne réelle
des éléments de la liste et de leur variance.
# let rec som l = match l with | [] -> 0
| h::t -> h + som t ;;
val som : int list -> int = <fun>
# let moy l = float_of_int (som l) /. float_of_int (List.length l) ;;
val moy : int list -> float = <fun>
# let carre x = x * x ;;
val carre : int -> int = <fun>
# let ecart l = let a = moy l in (moy (List.map carre l)) -. (a *. a) ;;
val ecart : int list -> float = <fun>
# let f l = (moy l , ecart l) ;;
val f : int list -> float * float = <fun>
ou mieux
let f l = let rec som l2 = match l2 with | [] -> 0
| h::t -> h + som t in let moy l3 = float_of_int (som l3) /.
float_of_int (List.length l3) in let carre x = x * x in let ecart l4 = let a = moy l4 in (moy
(List.map carre l4)) -. (a *. a) in (moy l , ecart l);;
15
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser – TD6
Exercice 1
1°/ Quel est le résultat de la séquence :
# let f n = n - 3 ;;
# let f n = if n < 3 then 0 else n * f(n-1) ;;
f 5 ;;
2°/ Quel est le résultat de :
# let rec f n = if n < 2 then 0 else n * f n/2 ;;
# f 6 ;;
Exercice 2
Ecrire une fonction qui calcule de manière récursive la somme des n premiers entiers.
Exercice 3
Ecrire une fonction qui calcule n!/m! Sous la forme n(n-1)(n-2) ...(m+1).
Exercice 4
Ecrire une fonction récursive qui donne le nombre de chiffres d'un entier écrit en base 10.
Exercice 5
Ecrire une fonction compte qui calcule le nombre d’éléments égaux à une valeur donnée dans
une liste.
Exercice 6
Ecrire une fonction qui calcule le maximum d'une liste non vide.
On donnera deux solutions, dont une récursive.
Exercice 7
Ecrire la somme de deux listes d'entiers, alignées sur le terme de droite.
16
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n° 7
Le but est de maîtriser la notion de récursivité terminale.
On dit que la fonction est récursive terminale quand l’appel à la fonction ne se fait pas à
l’intérieur d’un calcul.
On peut procéder par accumulation dans une variable cachée de l’utilisateur que l’on utilisera
comme accumulateur.
let f x = let rec fff acc xx = if “cas simple” then acc
else fff (nv valeur de l’acc) (cas plus simple)
in fff (intialisation de acc) x
double récursivité
Exemple :
let longueur l = let rec long acc ll = match ll with | [] -> acc
| h ::t -> long (acc+1) t
in long 0 l
17
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser – TD7
Exercice 1
En utilisant des fonctions récursives sous forme terminale écrire une fonction associant à une
liste d’entiers, un couple formé de la moyenne réelle et de la variance.
Exercice 2
Ecrire la fonction puissance comportant 2 variables x et n, de manière récursive.
On proposera deux solutions récursives dont l'une terminale.
Exercice 3
Ecrire la fonction récursive qui permet, étant donné un entier n positif ou nul, de calculer en
fonction de n, le terme un d'une suite définie par une relation de récurrence :
Les valeurs des deux premiers termes u0 et u1 seront des paramètres de la fonction.
On veillera à ce que la fonction ne provoque pas un stack overflow pour une valeur négative
de n.
Exercice 4
1°/ Ecrire une fonction récursive qui permet de rentrer au clavier, les éléments d'une liste
d'entiers positifs, il n'y aura aucune action quand la valeur entrée est négative.
2°/ Ecrire une fonction qui permet d’afficher les valeurs contenues dans la liste, une valeur
par ligne.
3°/ Ecrire une fonction qui affiche sur une ligne de l'écran, un nombre de X égal à la valeur de
l'élément de la liste, et cela pour tous les termes de la liste en respectant l'ordre.
4°/ Ecrire une fonction qui permet d'augmenter de la valeur constante 3, tous les éléments de
la liste.
5°/ Ecrire une fonction qui, à partir d'une liste, permet de créer une nouvelle liste comportant
le même nombre d'éléments, dont le premier élément est égal à la moyenne des deux premiers
termes de la liste, le dernier est égal à la moyenne des deux derniers termes de la liste et dont
les autres sont égaux à la moyenne de trois termes, la valeur de l’élément au rang j de la liste
et les valeurs des termes immédiatement avant et après dans la liste (j-1 et j+1). On affichera
les nouvelles valeurs contenues dans la liste ainsi construite. Les moyennes se calculent à
partir des valeurs de la liste initiale. On admet que la longueur de la liste en argument est
supérieure ou égale à 2.
On pourra construire des listes auxiliaires pour simplifier les calculs.
18
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n°8
Le but est de maîtriser la notion de type somme.
Type énuméré
Il est défini comme un ensemble de valeurs
type t_figure = | Carre | Rond | Losange | Triangle| Hexagone
Les membres commencent par une majuscule, ce sont des constructeurs
L’affichage se fait en construisant une fonction par cas qui assure l’impression de chaînes.
Type somme
On peut exprimer qu’un élément prend un nombre fini de valeurs OU une valeur d’un autre
type, le constructeur doit alors être précisé par un type
type t_figure2 = | Carre | Triangle | Rond | Generale of int
Définition récursive d’un type
type t_figure3 =
| Carre | Triangle | Rond
| Generale of int
|Hybride of t_figure3 * t_figure3
Toutes les opérations ou relations adaptées aux types énumérés doivent être définies
Exemple :
# type t_figure2 = | Carre | Triangle | Rond | Generale of int ;;
type t_figure2 = Carre | Triangle | Rond | Generale of int
Ecrire une fonction booléenne qui indique si une figure est un triangle.
# let sommet3 forme = match forme with | Triangle -> true
| Generale 3 -> true
| _ -> false
;;
val sommet3 : t_figure2 -> bool = <fun>
# sommet3 Carre ;;
- : bool = false
# sommet3 (Generale 3) ;;
- : bool = true
19
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser – TD8
Exercice 1
On considère l'expression suivante :
# let f x n = let a = 3 in let p x n = (x mod n) = 0 in
if p (x*x) n then 3 * x + -a else a + 5 ;;
1°/ Quelle est l'interprétation des types ?
2°/ Quelles sont les réponses aux expressions suivantes. 0n expliquera le comportement.
f 31 4 ;;
f -3 5 ;;
f ( 4 - 7) 2 ;;
f (4 , 2) ;;
f 21 9 ;;
Exercice 2
On considère la fonction f suivante :
let rec f l = match l with | [ ] -> [ ]
| h :: t -> (if (h mod 2) = 0 then (5 + (h / 2)) else (2 * h)) :: (f t) ;;
1°/ Quel est son effet pour la valeur [ 3 ; 2 ; 8 ; 1 ; 21 ] ?
2°/ En créant une fonction intermédiaire finter à définir, simplifier l’écriture de la fonction f.
3°/ Ecrire une fonction fterm sous forme terminale dont l’effet est le même que celui de la
fonction f.
4°/ Ecrire une fonction fmap dont l’effet est le même que celui de la fonction f et utilisant la
fonction List.map
Exercice 3
1°/ Ecrire une fonction qui construit une liste ayant un nombre n d'éléments tous égaux à x. n
et x sont les deux arguments.
2°/ Ecrire une fonction qui construit une liste ayant un nombre n d'éléments qui constituent les
n premiers nombres pairs.
Exercice 4
Ecrire la fonction qui rend la somme des éléments inférieurs à une valeur donnée dans une
liste d'entiers, cette valeur limite étant passée en paramètre.
Exemple : (sommeElementsPlusPetits [5;2;8;4;15;1] 7) rend 12 (la somme des éléments plus
petits que 7)
Exercice 5
1°/ Ecrire un type t_jour qui permet de modéliser l'ensemble des jours d'une semaine.
2°/ Ecrire une fonction qui permet de compter le nombre d’occurrences d'un jour donné dans
une liste d'éléments du type t_jour.
3°/ Ecrire une fonction qui à chaque jour associe le nombre d'heures travaillées. A lundi est
associé l'entier 6, à mardi l'entier 8, à mercredi l'entier 4, à jeudi l'entier 8, à vendredi l'entier
5, à samedi l'entier 4 et à dimanche l'entier 0.
4°/ On dispose d'une liste de jours. Ecrire une fonction dont le résultat est le nombre d'heures
travaillées. On donnera aussi une version terminale.
20
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n°9
Le but est de maîtriser la notion d’enregistrement.
Le type enregistrement permet de regrouper l’ensemble des éléments d’une fiche. La nature
de ces éléments n’est pas définie par une place mais par un mot clé.
type t_info = { info1 : float ; info2 : int ; info3 : string }
chaque terme de la définition constitue un champ
Définition de la valeur d’une variable x de type t_info
let x = {info1 = 3. ; info2 = 21 ; info3 = ″bonjour″ }
L’accès à un champ : x.info2
Pour modifier la valeur d’un champ il faut redéfinir la variable, c’est à dire l’ensemble des
champs
let x = {info1 = 3. ; info2 = 3 ; info3 = ″bonjour″ }
mais une affectation peut être réalisée globalement :
let y = x
un filtrage peut être réalisé dans les enregistrements sur les champs. Le symbole _ est
applicable sur tout champ
{info1 = 3 ; info2 = _ ; info3 = _}
Exemple :
Ecrire une fonction compte qui, dans une liste compte le nombre de termes qui satisfont une
condition qui est définie par une fonction argument de la fonction.
# let compte condi l = let rec compt acc cond ll = match ll with | [] -> acc | h ::t -> if cond h
then compt (acc + 1) cond t else compt acc cond t
in compt 0 condi l ;;
val compte : ('a -> bool) -> 'a list -> int = <fun>
Appliquer la fonction précédente à une liste dont les éléments sont des enregistrements de
type t_info dont on vérifie que le second est égal à 25.
# let condition x = match x with |{info1 = x1 ; info2 = x2 ; info3 = x3 } -> x2 = 25 ;;
val condition : t_info -> bool = <fun>
let liste = [{info1 = 1. ; info2 = 2 ; info3 = "bonjour" } ; {info1 = 1.543 ; info2 = 25 ; info3 =
"bon" } ; {info1 = 3.14 ; info2 = 25 ; info3 = "caml" } ; {info1 = 5.78 ; info2 = (-25) ; info3
= "licence" } ; {info1 = 0.25 ; info2 = 89 ; info3 = "paris" }];;
# compte condition liste ;;
- : int = 2
21
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser – TD9
Exercice 1
Ecrire une fonction jeu avec deux arguments max et nb qui permet de
• créer un entier aléatoire compris entre 0 et max
• proposer une hypothèse pour ce nombre
• indiquer si le nombre à trouver est plus ou moins grand que cette hypothèse
• faire des tentatives successives en nombre inférieur à nb.
Exercice 2
1°/ Ecrire une fonction qui répartit les éléments d'une liste en deux sous-listes ayant environ le
même nombre d'éléments, par exemple en mettant un élément sur deux dans chacune des
deux listes. Le résultat de la fonction est donc un couple de listes.
2°/ Ecrire une fonction, qui supposant les éléments de deux listes classés par ordre croissant,
construit une unique liste classée par ordre croissant.
3°/ Ecrire une fonction qui réalise le tri par ordre croissant d'une liste.
Exercice 3
En utilisant le type t_figure3 défini par
type t_figure3 =
| Carre | Triangle | Rond
| Generale of int
|Hybride of t_figure3 * t_figure3
écrire une fonction qui compte le nombre d’occurrences des figures avec 3 sommets dans une
liste d’éléments de type t_figure3.
Exercice 4
De manière à travailler avec des températures exprimées selon le cas en degrés Celsius ou en
degrés Fahrenheit on considère une structure de couple dont le premier élément est un
élément de type énuméré comportant deux valeurs associées à Celsius et à Fahrenheit
respectivement et le second élément est un réel, la valeur de la température exprimée dans
l’échelle mentionnée par le premier élément.
1°/ Ecrire une définition du type énuméré appelé t_degre.
2°/ Le lien entre la valeur C d’une température exprimée en degrés Celsius et la valeur F de la
même température exprimée en degrés Fahrenheit est donné par les relations :
9
5
! = 32 + ! !" ! = ! − 17,78
5
9
Ecrire une fonction conversion transformant une température exprimée par un couple en un
couple relevant de l’autre système.
Ecrire l’appel de fonction qui permet de connaître en degrés Celsius l’équivalent de 100
degrés Fahrenheit.
3°/ Ecrire une fonction booléenne superieur qui permet de comparer deux températures
exprimées par un couple.
4°/ Reprendre les questions 2 et 3 en utilisant un type somme pour modéliser la valeur des
températures.
22
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n°10
Le but est de compléter le type enregistrement et de voir des exemples d’utilisation de types
énumérés et enregistrement, en particulier la modélisation de graphes.
23
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser- TD10
Exercice 1
On considère le type t_note qui permet d'enregistrer les notes des différentes matières, math,
info, langue, humanité. Il y a 4 constructeurs. Les notes sont de type réel, comprises entre 0 et
20.
1°/ Ecrire le type t_note
2°/ Ecrire une fonction qui permet d'afficher une note accompagnée de l'affichage du nom de
la matière.
Puis une fonction qui affiche ligne par ligne les notes contenues dans une liste de notes de
type t_note.
3°/ On considère une liste de t_notes. Calculer la moyenne des notes de mathématiques
contenues dans la liste.
4°/ Ecrire une fonction somme qui calcule la somme terme à terme de deux listes de réels.
5°/ Ecrire une fonction qui calcule une liste contenant les moyennes des 4 matières, les
éléments de la liste seront de type t_note.
Exercice 2
1°/ Ecrire un type qui permet de modéliser une date par un enregistrement à 3 champs.
2°/ Ecrire une fonction qui permet de calculer la date du lendemain.
3°/ On dispose d'une liste de dates. Ordonner cette liste selon un ordre chronologique.
4°/ Ecrire une fonction qui permet de savoir si une liste contient des dates correspondant à un
mois donné en paramètre.
Exercice 3
Les clients d'un magasin sont connus par leur nom, leur numéro d'inscription qui correspond à
leur inscription, le code postal de leur lieu d'habitation, la somme dépensée dans le magasin
jusqu'à ce jour.
1°/ Ecrire le type enregistrement correspondant à ces données.
2°/ Une liste client contient l'ensemble des clients.
Ecrire une fonction qui permet de mettre à jour le champ "somme dépensée", c'est à dire
additionner une nouvelle somme à la valeur qui figure déjà dans le champ. Cette nouvelle
somme doit être un argument de la fonction, par contre le nom du client doit être lu dans la
fonction.
3°/ Ecrire une fonction calculant le pourcentage de clients qui ont dépensé une somme
supérieure à une valeur donnée, celle-ci devra figurer comme argument de la fonction. Cette
fonction doit pouvoir être utilisée pour toute liste d'éléments de type client.
4°/ Ecrire une fonction booléenne qui vérifie si un numéro est déjà utilisé comme numéro
d'inscription dans une liste.
5°/ Ecrire une fonction qui crée la liste des clients ayant un code postal donné.
24
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n°11
Le but est de mettre en œuvre tous les éléments du cours.
Modélisation et opérations sur les polynômes
25
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser – TD11
Exercice
Un étudiant est caractérisé par son nom, son prénom, son numéro d'inscription, son année
d'inscription, les semestres dans lesquels il suit des enseignements, son statut dans les 6
semestres de licence. Le statut peut prendre 3 valeurs admis, ajourne, rattrapage, non
concerné.
1°/ Ecrire un type t_statut qui permet de modéliser le statut d'un étudiant, on choisira un type
énuméré.
2°/ Pour un étudiant de L1, deux semestres sont utiles, quatre en L2 et 6 en L3. On créera un
type somme adapté au cursus de l'étudiant. En L1 on a un couple d'éléments contenant un
couple d'un réel (la moyenne générale est supposée nulle si le semestre n'est pas encore passé)
et d'un statut. Dans le cas d'un étudiant de L2, on a besoin d'un quadruplet et en L3 d'un
sextuplé. Ecrire un type t_result qui permet de modéliser ces cas (on utilisera un type
somme).
3°/ Ecrire une fonction l1tol2 qui permet d'interpréter un élément associé à un L1 comme un
élément de L2.
4°/ Ecrire un type enregistrement t_etudiant qui permet de regrouper les informations
relatives à un étudiant.
On dispose d'une liste d'éléments de type t_etudiant.
5°/ Ecrire une fonction booléenne present qui indique si un étudiant d'un numéro d'inscription
donné est dans la liste.
6°/ Ecrire une fonction nombre1 qui calcule le nombre d'étudiants inscrits en première année.
7°/ Ecrire une fonction nombre6 qui calcule le nombre d'étudiants ayant une mention très
bien au premier semestre.
8°/ Ecrire une fonction taux qui indique le pourcentage d'étudiants reçus à la première année
parmi les étudiants ayant un résultat aux deux premiers semestres.
Remarque pour forcer une variable x de type ta à prendre un type compatible tb on écrit :
(x:tb)
26
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Cours n°12
Révisions
27
Licence 1
UE Informatique
Programmation fonctionnelle
Année 2016 - 2017
Travail à réaliser – TD12
Exercice 1
La gestion d’un parc de voitures est liée aux préférences des utilisateurs. Les données
d’utilisation stockées sont : l’identifiant d’un utilisateur, les kilométrages de ses différentes
utilisations de voiture dans une liste d’entiers, la nature de l’utilisation de la voiture (de jour
ou de nuit), la nature du carburant utilisé.
Chaque utilisation est modélisée par un enregistrement à trois champs, un entier, une liste de
couples d’un entier et d’un énuméré indiquant la nature de l’utilisation (jour ou nuit) et un
énuméré.
1°/ Ecrire un type énuméré nommé t_carbur comportant au moins 3 valeurs correspondant à
de l’essence, du diesel et du biocarburant.
2°/ Ecrire un type enregistrement nommé t_utilisation qui permet de décrire une utilisation.
Les champs utilisés auront respectivement pour nom : ident, kilo et carbur.
Un exemple de valeur de type t_utilisation est
{ident = 314 ; kilo = [( 343 , Jour) ; ( 19 , Jour) ; ( 520 , Nuit) ] ; carbur = Essence}
3°/ Ecrire une fonction booléenne fcarbur qui teste si une variable de type t_utilisation
correspond à un utilisateur utilisant un carburant de type donné.
4°/ On considère une liste d’éléments de type t_utilisation. Ecrire une fonction fnbcarbur qui
calcule le nombre d’utilisateurs dans la liste utilisant une voiture fonctionnant avec un
carburant donné.
5°/ Ecrire une fonction fkilo qui calcule le nombre de kilomètres parcourus relatifs à une
variable de type t_utilisation.
6°/ Ecrire une fonction fnbkilo qui calcule le nombre de kilomètres parcourus par les
utilisateurs dans une liste d’éléments de type t_utilisation.
28
Téléchargement
Study collections