TP 1 - Introduction a CaML Light
CaML: (Categorical abstract Machine Language) est un langage de programmation fonctionnelle. La programmation fonctionnelle est un style de programmation où un programme est structuré en terme d'application de fonctions mathématiques. Caml light est une implémentation "legère" de Caml.
Pour telecharger CamlLight IDE aller a la PAGE..
3- Les Types de Base en Caml
Il y'a 5 types de base en Caml: les entiers, les réels, les booléens, les caractères et chaines de caractères, et les tuples.
Une expression doit etre terminée par ";;" pour que l'interpreteur Caml évalue l'expression.
Evaluer les Expressions Entières Suivantes:
======================================
Un entier (int) est une valeur comprise entre -1073741824 et 1073741823.
212;; 12/4;; 276 mod 23;; 21 + 23+ 17 + 3;; 4 * 91;; 10 / 6;;
(3 * 5) + (10 - 6);; 2.7 + 10;; int_of_float 2.1;; float_of_int 16;;
max 4 8;; min (-4) (-8);; abs 8; abs (-8);; succ 3;; pred 9;; succ (-3);; pred (-8);;
#212;;
- : int = 212
#
#12/4;;
- : int = 3
#
#276 mod 23;;
- : int = 0
#
#21 + 23+ 17 + 3;;
- : int = 64
#
#4 * 91;;
- : int = 364
#
#10 / 6;;
- : int = 1
#
#(3 * 5) + (10 - 6);;
- : int = 19
#
#2.7 + 10;;
Toplevel input:
>2.7 + 10;;
>^^^
This expression has type float,
but is used with type int.
#int_of_float 2.1;;
#- : int = 2
#
#float_of_int 16;;
- : float = 16.0
#
#max 4 8;;
- : int = 8
#
#min (-4) (-8);;
- : int = -8
#
#abs 8;;
- : int = 8
#
#abs (-8);;
- : int = 8
#
#succ 3;;
- : int = 4
#pred 9;;
- : int = 8
#succ (-3);;
- : int = -2
#pred (-8);;
- : int = -9
#
Evaluer les Expressions Réelles Suivantes:
===================================
3.45;; 10.0 /. 6.0;; 1.1 +. 2.2;; ceil 3.14;; floor 3.14;; exp 1.0;;
log 2.71828182846;; 3. ** 2.;; 3.45e10;; sqrt 25.;; abs_float 4.2;; abs_float (-4.2);;
max 4.5 8.5;; min (-4.5) (-8.5);;
Remarque:
On ne peut pas utiliser les opérations +, -, * et / sur les réels; il faut utiliser les opérations notées: +., -., *. et /.
On ne peut pas mélanger entier et réel en Caml. Il faudra convertir les entiers en réel (float_of_int) ou bien convertir les réels en entiers (int_of_float).
#3.45;;
- : float = 3.45
#
#10.0 /. 6.0;;
- : float = 1.66666666667
#
#1.1 +. 2.2;;
- : float = 3.3
#
#ceil 3.14;;
- : float = 4.0
#
#floor 3.14;;
- : float = 3.0
#
#exp 1.0;;
- : float = 2.71828182846
#
#log 2.71828182846;;
- : float = 1.0
#
#3. ** 2.;;
- : float = 9.0
#
#3.45e10;;
- : float = 34500000000.0
#
#sqrt 25.;;
- : float = 5.0
#
#abs_float 4.2;;
- : float = 4.2
#abs_float (-4.2);;
- : float = 4.2
#
#max 4.5 8.5;;
- : float = 8.5
#
#min (-4.5) (-8.5);;
- : float = -8.5
#
Evaluer les Expressions Booléennes Suivantes:
========================================
true;; not true;; true && false;; true || false;; true or false;;
1<2;; 1<=2;; 0<1 & 3<9;; (not false) or true;; "un"<"deux";;
#true;;
- : bool = true
#
#not true;;
- : bool = false
#
#true && false;;
- : bool = false
#
#true || false;;
- : bool = true
#
#true or false;;
- : bool = true
#
#1<2;;
- : bool = true
#
#1<=2;;
- : bool = true
#0<1 & 3<9;;
- : bool = true
#(not false) or true;;
- : bool = true
#
#"un"<"deux";;
- : bool = false
#
Evaluer les Expressions Caractères et Chaines de Caractères Suivantes:
=============================================================
`a`;; int_of_char `a`;; char_of_int 97;; "a";; "ceci est une c" ^ "haine de caracteres!";;
"toutou".[5];; "kArim".[1];; string_length "KADER";; sub_string "Bonjour" 0 3;;
`a`;;
- : char = `a`
#int_of_char `a`;;
- : int = 97
#char_of_int 97;;
- : char = `a`
#"a";;
- : string = "a"
#"ceci est une c" ^ "haine de caracteres!";;
#- : string = "ceci est une chaine de caracteres!"
#"toutou".[5];;
#- : char = `u`
#"kArim".[1];;
#- : char = `A`
#string_length "KADER";;
#- : int = 5
#sub_string "Bonjour" 0 3;;
#- : string = "Bon"
#
#`a`;;
- : char = `a`
#string_of_char `a`;;
- : string = "a"
#
Remarques:
int_of_char: retourne le code ascii en décimal du caractère
char_of_int: retourne le caractère du code ascii donné
^: fait la concaténation de 2 chaines de caractères
ch.[i]: retourne le caractère d'indice i de la chaine ch (les indices commencent de 0 ch.[0] retourne le premier caractère)
string_length ch: retourne le nombre de caractères de la chaine ch
sub_string ch i l: retourne la chaine commençant à partir du caractère d'indice i et ayant l caractères
Noter les équivalences suivantes entre Caml light et OCaml:
Caml Light Equivalent en OCaml
string_length String.length
sub_string String.sub
string_of_char Char.escaped
Evaluer les Expressions Tuples Suivantes:
====================================
Tuples: combinaison de valeurs pour former des paires, triplets, quadruplets, ...
Tuple: composants l'un à la suite de l'autre separés par "," avec des parenthèses (pour augmenter la lisibilité mais ne sont pas nécessaires). Le type d'un tuple est le type de ces composants separés par une " *".
(1,2);; 1,2,3;; (1, (2,3));; (12, "October");; ("coucou", 1.2, (`A`,2));;
fst(12, "October");; snd(12, "October");; (12, "october", true);;
Remarque:
Pour les tuple pairs:
fst(p1, p2) retourne p1
snd(p1, p2) retourne p2
#(1,2);;
- : int * int = 1, 2
#1,2,3;;
- : int * int * int = 1, 2, 3
#(1, (2,3));;
- : int * (int * int) = 1, (2, 3)
#(12, "October");;
- : int * string = 12, "October"
#("coucou", 1.2, (`A`,2));;
- : string * float * (char * int) = "coucou", 1.2, (`A`, 2)
#fst(12, "October");;
- : int = 12
#snd(12, "October");;
- : string = "October"
#(12, "october", true);;
- : int * string * bool = 12, "october", true
#
4. Les Opérateurs de Comparaison en Caml
Les opérateurs suivants s'appliquent aux entiers, aux réels, aux caractères ainsi que pour les chaines de caractères. Une comparaison utilisant un des symboles ci-dessous ne doit concerner que 2 objets de même type:
> : Superieur
>= : Superieur ou Egale
< : Inferieur
<= : Inferieur ou Egale
= : Egalite
<> : Different
Les opérateurs suivants (Noter le point '.' a la fin) s'appliquent uniquement aux réels:
>. : Superieur
>=. : Superieur ou Egale
<. : Inferieur
<=. : Inferieur ou Egale
=. : Egalite
<>. : Different
Remarques:
1) Pour les caractères on a suivant le code ASCII (ordre lexicographique):
...< '0' < '1' < '2' < ... <'9'< . . . <'A' < 'B' < 'C' < ... <'Z'< . . . <'a' < 'b' < 'c' ... <'z' < ...
Le caractère '0' a le code ascii 48, le caractère '1' a le code ascii 49, ..., le caractère '9' a le code ascii 57
Le caractère 'A' a le code ascii 65, le caractère 'B' a le code ascii 66, ..., le caractère 'Z' a le code ascii 90
Le caractère 'a' a le code ascii 97, le caractère 'b' a le code ascii 98, ..., le caractère 'z' a le code ascii 122
2) Les chaines de caractères sont comparées selon l'ordre lexicographique.
La chaine vide "" est < à toutes les autres chaines.
Si on a 2 chaines A et B tels que: A = "a1a2a ... am" (m caractères) et B = "b1b2 ... bn" (n caractères) alors:
A < B si: 'a1' < 'b1' ou ('a1' = 'b1' et "a2a3 ... am" < "b2b3 ... bn")
A > B si: 'a1' > 'b1' ou ('a1' = 'b1' et "a2a3 ... am" > "b2b3 ... bn")
A = B si: 'a1' = 'b1' et "a2a3 ... am" = "b2b3 ... bn" (c'est à dire exactement le même nombre de caractères (m=n) et exactement les même caractères dans le meme ordre).
3) Il existe aussi en Caml les 2 opérateurs: == et != (negation de ==).
L'opérateur == teste l'égalite physique des valeurs (identité des adresses mémoire en cas de valeurs allouées). Il faut faire attention à l'usage de ces 2 opérateurs dans le cas des chaines de caractères et des réels. On utilisera uniquement les opérateurs "=" et "<>" dans les TPs qui suivent pour tester l'egalité et l'inegalité.
5. Le Type unit, les Impressions et les lectures du clavier en Caml
Pour afficher une expression en Caml, les fonctions prédefinies: print_int, print_float, print_char et print_string permettent cela. Ces fonctions prennent un entier, un réel, un caractère ou une chaine de caractères et affichent cet argument mais ne produisent pas de résultat: ceci est exprime par le type unit qui signifie qu'il n'y a pas de résultat (unit est un peu l'équivalent de void en C).
Pour lire du clavier les fonctions prédefinies: read_int, read_float et read_line permettent de lire respectivement un entier, un réel ou une chaine de caractères.
#print_int;;
- : int -> unit = <fun>
#print_float;;
- : float -> unit = <fun>
#print_char;;
- : char -> unit = <fun>
#print_string;;
- : string -> unit = <fun>
#
#let x = 12;;
x : int = 12
#print_int x;;
12- : unit = ()
# read_int;;
- : unit -> int = <fun>
# read_float;;
- : unit -> float = <fun>
#read_line;;
- : unit -> string = <fun>
#let x = read_int();;
15
x : int = 15
#print_int x;;
15- : unit = ()
#let x = read_float();;
18.7
x : float = 18.7
#print_float x;;
18.7- : unit = ()
#let x = read_line();;
abcdef ghi
x : string = "abcdef ghi"
#print_string x;;
abcdef ghi- : unit = ()
6. Définition
Une définition est une déclaration qui associe un nom à une expression. Il y'a 2 types de déclarations: les déclarations globales et les déclarations locales.
6.1 Déclaration Globale
Syntaxe:
let nom = expression;;
ou nom représente l'identificateur et expression l'expression qui lui est associée.
Exemple:
#let x = 12;;
x : int = 12
#x;;
- : int = 12
Remarque: Caml est case sensitive. Les noms en minuscule ne sont pas les même que les noms en majuscule.
#X;;
Toplevel input:
>X;;
>^
The value identifier X is unbound.
#
Déclarations Globales Simultanées
Syntaxe
let nom1 = expression1
and
nom2 = expression2
and ...
nomn = expressionn;;
Exemple:
#let x = 2 and y = 5;;
x : int = 2
y : int = 5
#
#let x = 4;;
x : int = 4
#
#x+3;;
- : int = 7
#
#let x =5.8;;
x : float = 5.8
#
#x +. 3.1;;
- : float = 8.9
#
#let a=3 and b=4;;
a : int = 3
b : int = 4
#a+b;;
- : int = 7
#
6.2 Déclaration Locale
Syntaxe:
let nom = expression1 in expression2;;
Exemple:
#let x = 6 in x * x;;
- : int = 36
#
Déclarations Locales Simultanées
Syntaxe
let nom1 = expression1
and
nom2 = expression2
and ...
nomn = expressionn
in expression;;
Exemple:
#let x=(1, "coucou") and y=("hello", 2.1) in (snd x, fst y);;
- : string * string = "coucou", "hello"
#
let a=1 and b=2*a in a+b;;
- : int = 7
#
Noter dans l'expression ci-dessus le a locale égale à la valeur 1 est connu et utilisé (apres le in) dans l'expression a+b mais dans la déclaration b=2*a c'est le a globale qui est utilisé (le a locale est connu uniquement après le in). Le a globale a été declaré avec la valeur 3 dans l'exemple auparavant (expression let a=3 and b=4;;).
let a= (let b=2 in 6+b);;
a : int = 8
#
#let a =1 in let b=2*a in b + a;;
- : int = 3
#
Par contre dans l'exemple ci-dessus le a locale est connu après le in; donc c'est le a locale qui a la valeur 1 qui est utilisé dans let b=2*a (et aussi dans b+a).
6.3 If Statement
Syntaxe:
if expBoolean then exp1 else exp2;;
La valeur de cette expression est exp1 si expBoolean s'evalue à Vrai (True);
sinon c'est exp2 (expBoolean s'evalue dans ce cas à Faux :False).
Remarque: Il faut que exp1 et exp2 soient de même type.
If sans clause else.
Syntaxe:
if expBoolean then exp;;
Un if sans clause else correspondante est automatiquement completé par une clause else (). Comme else () a le type unit il faut dans ce cas que exp soit aussi de type unit. Ce genre de construction est utilisé par exemple dans le cas où on fait une impression. Comme par exemple:
#let x = 13;;
x : int = 13
#if x>0 then print_int x;;
13- : unit = ()
#
Exemples de if statement
#if true then 1 else 0;;
- : int = 1
#
#(if 3=5 then 8 else 10) + 6;;
- : int = 16
#
#let x=3 in if x=0 then 0 else 15/x;;
- : int = 5
#
#(if 3=5 then 8 else 10) + 6;;
- : int = 16
#let x=3 in if x=0 then 0 else 15/x;;
- : int = 5
#let x=3 in let y=2 in x + y;;
- : int = 5
#
Exercice: Evaluer dans cet ordre les expressions suivantes:
let x = 2 in x * x;;
x;;
let x = 12;;
x;;
let x = 4 and y = 5 in x + y;;
x;;
y;;
let y = (let x = 3 and z = 8 in x * z);;
x;;
y;;
z;;
let z = (if x=y then "XEgaleY" else "XDifferentY");;
z;;
x;;
y;;
let x = (if y>0 then "YPositif" else "YNonPositif");;
x;;
let w1 = (let a1=("12", "Douze") and a2=("13", "Treize") and a3=("14", "Quatorze") in
(fst a1 ^ fst a2 ^ fst a3, snd a1 ^ " " ^ snd a2 ^ " " ^ snd a3));;
let w2 = (let a1=("12", "Douze") and a2=("13", "Treize") and a3=("14", "Quatorze") in
(fst a1 ^ snd a2 ^ fst a3, snd a1 ^ fst a2 ^ fst a3, fst a1 ^ fst a2 ^ snd a3));;
let w3 = (let a1=12 and a2=13 and a3=14 in (string_of_int a1 ^ string_of_int a2 ^ string_of_int a3, max a1 (min a2 a3)));;
w3;;
w1;;
let w4 = (let l = string_length (fst w1 ^ snd w1) and w5 = (fst w1 ^ snd w1) in (w5, l));;
let w5 = (let l = string_length (fst w4) and w6 = (fst w4) in (w6.[0], w6.[l - 1]));;
w5;;
let w6 = (let l = string_length (snd w1) and w5 = snd w1 in
if l>10 then sub_string w5 10 (l - 10) else sub_string w5 0 (l - 1));;
w6;;
let w7 = (let l = string_length (fst w1) and w5 = fst w1 in
if l>10 then sub_string w5 10 (l - 10) else sub_string w5 0 (l - 1));;
w7;;
let x1 = 3 and x2 = x1 + 1 in x1 + x2;;
let x1 = 3 in let x2 = x1 + 1 in x1 + x2;;
let x1 = 11;;
let x1 = 3 and x2 = x1 + 1 in x1 + x2;;
