Cours alternatif d’OCaml

Logo OCaml
VI — Polymorphisme

Entraînement

Voici quelques exercices d’entraînement sur le polymorphisme. Ils sont beaucoup plus abstraits que ceux d’avant, mais on n’a malheureusement pas trop le choix : quand on commence à manipuler des types génériques, il faut réfléchir !

On va définir un type optionnel, qui indique qu’une valeur peut-être présente ou non.

type 'a optionnel =
  | None (* On a rien *)
  | Some of 'a (* On a une valeur *)

Quel est le type de ces fonctions ?

let qqch_ou_alors opt par_defaut =
  match opt with
  | Some(x) -> x
  | None -> par_defaut
let contient opt x =
  match opt with
  | None -> false
  | Some(y) -> x = y
let multiplie opt x =
  match opt with
  | None -> None
  | Some(a) -> Some(a *. x)

On va maintenant créer un type dico qui prend deux paramètres de types : un pour des clés, un pour des valeurs. Ce type sert à associer une valeur à une clé, pour ensuite pouvoir retrouver les valeurs en fonction de leurs clés. Ce type ressemble donc au type dictionnaire en Python, la seule différence est que toutes les clés ont le même type, et toutes les valeurs aussi, on ne peut pas mélanger.

On va donc :

Proposition de correction
type ('c, 'v) dico =
  | Vide
  | Element of 'c * 'v * ('c, 'v) dico

let creer = Vide

let rec definir (cle : 'c) (valeur : 'v) (dic : ('c, 'v) dico) : ('c, 'v) dico =
  match dic with
  | Element(_, _, suite) -> definir cle valeur suite
  | Vide -> Element(cle, valeur, Vide)

let rec obtenir (cle : 'c) (dic : ('c, 'v) dico) : 'v =
  match dic with
  | Vide -> failwith "Clé non trouvée"
  | Element(c, v, suite) ->
    if cle = c then
      v
    else
      obtenir cle suite

let rec supprimer (cle : 'c) (dic : ('c, 'v) dico) : ('c, 'v) dico =
  match dic with
  | Vide -> Vide
  | Element(c, v, suite) ->
    if c = cle then
      suite
    else
      Element(c, v, supprimer cle suite)