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

2- Types récursifs

I. Définition inductive d'un ensemble

Idée : définir un ensemble d'objets "par récurrence".

Définition : ensemble inductif

Un ensemble inductif est défini par :

  • un ensemble de cas de base ;
  • un ensemble de constructeurs, qui sont des fonctions où .

On pose :

Alors, on a .

En français : on peut appliquer les constructeurs autant de fois que nécessaire (en se limitant à un nombre fini de fois) à partir des cas de base, pour obtenir tous les éléments de .

Par exemple :

II. L'équivalent OCaml : les types récursifs

a) Types énumération

On peut écrire des types énumération en OCaml :

OCaml

Loading editor...

type classe =
    | MPSI_1
    | MPSI_2
    | MP_1
    | MP_2
    | MP_ET;;

Une valeur de type classe peut alors prendre une des 5 valeurs définies (et rien d'autre !). Par exemple :

OCaml

Loading editor...

let ma_classe: classe = MPSI_1;;

On peut également stocker des données arbitraires dans une des options :

OCaml

Loading editor...

type classe =
    | MPSI_1
    | MPSI_2
    | MP_1
    | MP_2
    | MP_ET
    | Autre of string;;

let ma_classe: classe = Autre "BCPST";;

La construction match est alors très utile, car elle permet de traiter séparément chaque cas du type énumération.

OCaml

Loading editor...

let nb_eleves (c: classe): int = match c with
    | MPSI_1 -> 49
    | MPSI_2 -> 43
    | MP_1 -> 38
    | MP_2 -> 36
    | MP_ET -> 40
    | Autre nom -> failwith ("classe inconnue : " ^ nom);;
OCaml

Loading editor...

nb_eleves MP_1;;
nb_eleves MPSI_2;;

b) Types récursifs

On peut également faire des types récursifs, c'est-à-dire utiliser le type classe dans sa propre définition !

Bien sûr, il faut que certains variants n'utilisent pas de type récursif, pour qu'on puisse "s'arrêter".

OCaml

Loading editor...

type classe = MP | MPSI | PCSI | PC | Autre of string | DoubleNiveau of classe * classe;;

let classe4 = DoubleNiveau (MP, PC);;

let classe5 = DoubleNiveau (DoubleNiveau (MP, PC), Autre "MPI");;

III. Petit point sur les listes

En OCaml, on pourrait définir nous-mêmes un type de liste :

OCaml

Loading editor...

type liste = Vide | El of int * liste;;

Par exemple, la liste [1; 2; 3] s'écrit alors :

OCaml

Loading editor...

let l : liste = El (1, El (2, El (3, Vide)));;

(* la longueur d'une liste, par récurrence sur sa structure *)
let rec longueur (l: liste): int = match l with
    | Vide -> 0
    | El (_, q) -> 1 + longueur q;;

longueur l;;

Exercices

Exercice 1

Avec le type liste de la partie III, écrire une fonction somme : liste -> int, puis une fonction vers_liste : liste -> int list qui convertit une liste en liste OCaml.

OCaml

Loading editor...

let rec somme (l : liste) : int = match l with
    | Vide -> 0
    | El (x, q) -> x + somme q;;

let rec vers_liste (l : liste) : int list = match l with
    | Vide -> []
    | El (x, q) -> x :: vers_liste q;;
Exercice 2

Définir un type carte pour représenter une carte à jouer : une couleur (pique, cœur, carreau, trèfle) et une valeur (un entier de 2 à 10, valet, dame, roi ou as). Écrire une fonction points : carte -> int qui donne 11 points pour un as, 10 pour une figure, et la valeur sinon.

OCaml

Loading editor...

type couleur = Pique | Coeur | Carreau | Trefle;;
type valeur = Nombre of int | Valet | Dame | Roi | As;;
type carte = valeur * couleur;;

let points ((v, _) : carte) : int = match v with
    | As -> 11
    | Valet | Dame | Roi -> 10
    | Nombre n -> n;;

points (Dame, Coeur);;
Exercice 3

Avec le type classe récursif de la partie II.b, écrire une fonction nb_niveaux : classe -> int qui compte le nombre de classes "simples" dans une classe : nb_niveaux classe5 doit valoir 3.

OCaml

Loading editor...

let rec nb_niveaux (c : classe) : int = match c with
    | DoubleNiveau (c1, c2) -> nb_niveaux c1 + nb_niveaux c2
    | _ -> 1;;