Skip to main content Informatique en prépa - Lycée Malherbe 

1- Introduction au langage OCaml

I. Le langage OCaml

Logo OCaml

OCaml est un langage fonctionnel, basé en partie sur la récursivité, qui est utilisé en option informatique en prépa.

Syntaxe de base du langage

a) Valeurs et types

En OCaml, chaque valeur a un type, que l'interpréteur calcule tout seul (on dit qu'il l'infère) et affiche :

OCaml

Loading editor...

42;;
3.14;;
true;;
'a';;
"bonjour";;

Les types de base sont int (entiers), float (flottants), bool (booléens), char (caractères, entre apostrophes) et string (chaînes, entre guillemets).

Dans l'interpréteur, chaque phrase se termine par ;;. Le site l'ajoute à la fin d'une cellule si vous l'oubliez.

b) Opérations

Les opérations sur les entiers et sur les flottants sont différentes : les opérateurs sur les flottants ont un point.

OCaml

Loading editor...

3 + 4 * 2;;
7 / 2;;         (* division entière *)
7 mod 2;;       (* reste *)
3.5 +. 1.2;;
7.0 /. 2.0;;
float_of_int 7 /. 2.0;;   (* conversion explicite *)

OCaml ne convertit jamais automatiquement un type en un autre :

OCaml

Loading editor...

3 + 1.5;;

Les comparaisons s'écrivent =, <> (différent), <, <=, >, >=, et les opérations booléennes &&, || et not. Les chaînes se concatènent avec ^.

OCaml

Loading editor...

3 <> 4 && not (2 > 5);;
"bon" ^ "jour";;

c) Définitions

On donne un nom à une valeur avec let. Une fois définie, une variable ne peut pas être modifiée (on peut seulement définir une nouvelle variable du même nom).

OCaml

Loading editor...

let x = 5;;
let y = x * 2;;

Une définition locale s'écrit let ... in ... : la variable n'existe que dans l'expression qui suit le in.

OCaml

Loading editor...

let aire = let rayon = 2.0 in 3.14 *. rayon *. rayon;;

d) Conditions

En OCaml, if ... then ... else ... est une expression : elle a une valeur, comme l'opérateur ternaire. Les deux branches doivent avoir le même type.

OCaml

Loading editor...

let signe = if x >= 0 then "positif" else "négatif";;

e) Fonctions

On définit une fonction avec let, suivi de son nom et de ses arguments (sans parenthèses ni virgules). On l'appelle de la même manière, en écrivant les arguments à la suite :

OCaml

Loading editor...

let carre x = x * x;;
carre 5;;

let moyenne a b = (a +. b) /. 2.0;;
moyenne 3.0 4.0;;

L'interpréteur affiche le type de la fonction : int -> int pour une fonction qui prend un entier et renvoie un entier, float -> float -> float pour une fonction qui prend deux flottants. On peut aussi préciser les types soi-même, ce qui est recommandé :

OCaml

Loading editor...

let perimetre (longueur : float) (largeur : float) : float = 2.0 *. (longueur +. largeur);;

Une fonction récursive se définit avec let rec :

OCaml

Loading editor...

let rec factorielle (n : int) : int =
    if n = 0 then 1 else n * factorielle (n - 1);;

factorielle 10;;

Pour passer le résultat d'un calcul en argument, il faut des parenthèses : factorielle (n - 1), et non factorielle n - 1, qui calcule (factorielle n) - 1.

f) Filtrage

La construction match compare une valeur à des motifs, dans l'ordre, et renvoie le résultat du premier motif qui correspond (_ correspond à n'importe quoi) :

OCaml

Loading editor...

let nom_jour (n : int) : string = match n with
    | 1 -> "lundi"
    | 2 -> "mardi"
    | 6 | 7 -> "week-end"
    | _ -> "un autre jour";;

nom_jour 2;;
nom_jour 7;;

g) Listes

Une liste contient des éléments du même type, séparés par des points-virgules. Une liste est soit vide ([]), soit un élément suivi d'une liste : x :: q (x est la tête, q la queue).

OCaml

Loading editor...

let l = [1; 2; 3];;
0 :: l;;
l @ [4; 5];;   (* concaténation *)

On parcourt une liste par filtrage et récursivité :

OCaml

Loading editor...

let rec somme (l : int list) : int = match l with
    | [] -> 0
    | x :: q -> x + somme q;;

somme [1; 2; 3; 4];;

II. Étude de cas : les formules

On étudie des formules limitées :

Par exemple, est une formule.

a) Définition par induction

On tente de définir les formules. Une addition entre deux "trucs", , est une formule. Que peuvent être ces "trucs" ?

Ils peuvent être n'importe quelle formule ! On arrive donc à la définition suivante :

Définition inductive : formule

On se donne un ensemble de variables . Une formule est :

  • soit une variable ;
  • soit, si et sont des formules :
    • , la négation de ;
    • , l'addition ;
    • , la multiplication.

b) Et en OCaml ?

On peut traduire directement cette définition en un type OCaml :

OCaml

Loading editor...

type formule =
    | Var of char
    | Neg of formule
    | Add of formule * formule
    | Mul of formule * formule;;

(* la formule (a + b) * (a + (-b)) *)
let f = Mul (Add (Var 'a', Var 'b'), Add (Var 'a', Neg (Var 'b')));;

Exercices

Exercice 1

Écrire une fonction taille : formule -> int qui compte le nombre de variables et d'opérations d'une formule. Par exemple, la formule f ci-dessus a une taille de 8.

OCaml

Loading editor...

let rec taille (f : formule) : int = match f with
    | Var _ -> 1
    | Neg g -> 1 + taille g
    | Add (g, d) | Mul (g, d) -> 1 + taille g + taille d;;
Exercice 2

Écrire une fonction evalue : formule -> (char -> int) -> int qui calcule la valeur d'une formule, étant donné une fonction qui donne la valeur de chaque variable.

OCaml

Loading editor...

let rec evalue (f : formule) (valeur : char -> int) : int = match f with
    | Var v -> valeur v
    | Neg g -> - (evalue g valeur)
    | Add (g, d) -> evalue g valeur + evalue d valeur
    | Mul (g, d) -> evalue g valeur * evalue d valeur;;

evalue f (fun v -> if v = 'a' then 3 else 2);;   (* (3 + 2) * (3 - 2) = 5 *)
Exercice 3

Écrire une fonction en_texte : formule -> string qui renvoie l'écriture d'une formule, avec des parenthèses autour de chaque opération. Par exemple, pour f : "((a + b) * (a + (-b)))".

OCaml

Loading editor...

let rec en_texte (f : formule) : string = match f with
    | Var v -> String.make 1 v
    | Neg g -> "(-" ^ en_texte g ^ ")"
    | Add (g, d) -> "(" ^ en_texte g ^ " + " ^ en_texte d ^ ")"
    | Mul (g, d) -> "(" ^ en_texte g ^ " * " ^ en_texte d ^ ")";;