Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
(**********************************************************************)
(* 1.1.1 *)
(3 * 2) + (5 / 2);;
3.2 +. (7.4 /. 2.0);;
"AC" ^ "/" ^ "DC";;
true || (false && false);;
(* && est prioritaire sur || *)
(false && false) || true;;
(* 3 < 2.0 provoque une erreur car 3 et 2.0 n'ont pas le même type *)
(**********************************************************************)
(* 1.1.2 *)
(* float_of_int 3.0 provoque une erreur car 3.0 n'est pas un int *)
float_of_int 3;;
int_of_float;;
int_of_float 3.5 + 2;;
float_of_int (int_of_float 3.6 + 2) +. 1.5;;
(not false) && false;;
2 < 3 && "b" < "ab";;
(**********************************************************************)
(* 1.1.3 *)
let x1 = 3.5 +. float_of_int 2 in
x1 +. 3.0
;;
let x1 = 3.5 +. float_of_int 2 in
let x2 = x1 *. x1 in
x2 *. 2.0
;;
(**********************************************************************)
(* 1.1.4 *)
(if true then 3 else 5) > 4
(**********************************************************************)
(* 1.2 *)
let f x = x + 1;;
3 + f 3
let discriminant a b c = (b *. b) -. (4.0 *. a *. c)
(* Le type affiche par l'interpréteur est float -> float -> float -> float *)
(** [discriminant a b c] calcule le discriminant d'un trinôme. Cette fonction
est utile pour trouver les racines d'un trinôme.
@param a le coefficient d'ordre 2
@param b le coefficient d'ordre 1
@param c le coefficient d'ordre 0
@return le discriminant *)
let discriminant (a : float) (b : float) (c : float) : float =
(b *. b) -. (4.0 *. a *. c)
;;
discriminant;;
discriminant 2.0 8.0 8.0
(* Erreur de type sur l'utilisation de a dans la def suivante: *)
(*
let discriminant (a:int) (b:float) (c:float): float =
b *. b -. 4.0 *. a *. c;;
*)
(**********************************************************************)
(* 1.3.1 *)
type couleur = Rouge | Jaune | Bleu;;
(* La valeur Rouge est bien définie et reconnue comme étant de type couleur *)
Rouge;;
(* L'égalité est bien (pré)définie sur les couleurs *)
Rouge = Rouge;;
Rouge != Bleu;;
(* De même il existe un ordre par défaut sur les couleurs *)
Bleu > Jaune
type couleur = Rouge | Jaune | Bleu | Violet | Orange | Vert
type couleur =
| Rouge
| Jaune
| Bleu
| Violet
| Orange
| Vert
| RJB of int * int * int
;;
(* le type est "int * float" c'est-à-dire une paire d'int et de float *)
3, 5.6;;
(* c'est le triplet de type int * int * int *)
3, 5, 6
(**********************************************************************)
(* 1.3.2 *)
let nom_couleur c =
match c with
| Rouge -> "rouge"
| Jaune -> "jaune"
| Bleu -> "bleu"
| Vert -> "vert"
| Violet -> "violet"
| Orange -> "orange"
| _ -> "mélange"
(*
let nom_couleur c =
match c with
| Rouge -> "rouge"
| Jaune -> "jaune"
| Bleu -> "bleu"
| Vert -> "vert"
| Violet -> "violet"
| Orange -> "orange";;
Erreur: this pattern-matching is not exhaustive.
Elle indique que le match ne couvre pas tous les cas possibles.
*)
(*
let nom_couleur c =
match c with
| _ -> "mélange"
| Rouge -> "rouge"
| Jaune -> "jaune"
| Bleu -> "bleu"
| Vert -> "vert"
| Violet -> "violet"
| Orange -> "orange";;
Erreur: this pattern-matching is not exhaustive.
Elle indique que le match ne couvre pas tous les cas possibles.
*)
(** Génère le paragraphe pour [n] bouteilles de bières.
@param n
le nombre de bouteilles de bièere sur le mur au début du paragraphe.
@return le paragraphe *)
let paragraphe_bottles (n : int) : string =
match n with
| 0 ->
"No more bottles of beer on the wall, no more bottles of beer.\n"
^ "Go to the store and buy some more, 99 bottles of beer on the wall."
| 1 ->
"1 bottle of beer on the wall, 1 bottle of beer.\n"
^ "Take one down and pass it around, no more bottles of beer on the wall."
| 2 ->
"2 bottles of beer on the wall, 2 bottles of beer.\n"
^ "Take one down and pass it around, 1 bottle of beer on the wall."
| k ->
string_of_int k ^ " bottles of beer on the wall, " ^ string_of_int k
^ " bottles of beer.\n" ^ "Take one down and pass it around, "
^ string_of_int (k - 1)
^ " bottles of beer on the wall."
;;
(* tests *)
paragraphe_bottles 0;;
paragraphe_bottles 1;;
paragraphe_bottles 2;;
paragraphe_bottles 7
(**********************************************************************)
(* 2.1 *)
(** Renvoie la somme des n premiers entiers
@param n le nombre d'entiers à sommer
@return la somme *)
let rec sum_n (n : int) : int = if n <= 0 then 0 else n + sum_n (n - 1)
(** [factorielle n] calcule la factorielle des [n] premiers entiers
@param n doit être supérieur ou égal à 1
@return !n *)
let rec factorielle n = if n <= 1 then 1 else n * factorielle (n - 1)
(**********************************************************************)
(* 2.2 *)
(* Erreur car on essaie d'ajouter une string dans une int list
"2" :: 3 :: [];;
*)
(** Cette fonction calcule la longueur d'une liste de `string`.
@param l la liste dont on veut la longueur
@return la longueur de l *)
let rec longueur (l : string list) : int =
match l with [] -> 0 | _ :: l2 -> 1 + longueur l2
(* La valeur de l'élément de list n'est pas utilisée dans le deuxième cas du match.
On a donc pas besoin de la recupérer dans une variable et on met _ pour plus de clarté. *)
(** Cette fonction calcule la somme des éléments de la liste
@param l la liste dont on veut additionner les éléments
@return la somme des éléments de la liste *)
let rec sum_f (l : float list) : float =
match l with [] -> 0.0 | x :: l2 -> x +. sum_f l2
(** Cette fonction concatène les éléments de la liste en les séparant par [sep].
@param l la liste dont on veut concaténer les éléments
@param sep le séparateur
@return
les éléments de la liste [l] concaténé et séparés les uns des autres par
[sep] *)
let rec join_s (l : string list) (sep : string) : string =
match l with
| [] -> ""
| s :: [] -> s
| s :: l2 ->
(* Plus général que le cas précédent car l2 n'est pas forcément vide.
Comme le match applique le premier cas dans l'ordre du programme,
Les listes à 1 élément ne passent pas dans le 3eme cas du match. *)
s ^ sep ^ join_s l2 sep
;;
(* test *)
join_s [ "a"; "b"; "c" ] "|"
(** Cette fonction créée une liste des int de n à 0 inclus.
@param n l'int de début de liste
@return la liste des entiers décroissants *)
let rec liste_n_0 (n : int) : int list =
if n <= 0 then [ 0 ] else n :: liste_n_0 (n - 1)
;;
(* test *)
liste_n_0 12
(** [bottles_of_list [n1; n2; ...]] crée la liste des paragraphes de la chanson
99 bottles of beer pour n1 puis n2 ... bouteilles.
@param l la liste des nombres de bouteilles à transformer
@return la liste des paragraphes correspondant aux int de l *)
let rec bottles_of_list (l : int list) : string list =
match l with
| [] -> []
| n :: l2 -> paragraphe_bottles n :: bottles_of_list l2
let chanson_99_bottles =
let nums = liste_n_0 99 in
let paragraphes = bottles_of_list nums in
join_s paragraphes "\n\n"
;;
print_endline chanson_99_bottles