La fonction de reconstruction des arbres est un peu plus subtile.

(*
   La mission de do_parse l est
   * Si l est de la forme la @ rem où la représente un arbre a,
     alors renvoie la paire a,rem.

   * Sinon, fais ce que dois, advienne que pourra
     (cf. assert false, devise de Du Guesclin)
*)


let rec do_parse l = match l with
Zero::Zero::rem -> Feuille Blanc, rem
Zero::Un::rem -> Feuille Noir, rem
Un::rem ->
    let a1,rem = do_parse rem in
    let
 a2,rem = do_parse rem in
    let
 a3,rem = do_parse rem in
    let
 a4,rem = do_parse rem in
    Noeud (a1,a2,a3,a4),rem
| _ -> assert false

let liste_vers_arbre l = let a,_ = do_parse l in a

Ici encore, le filtrage est bien utile. Le dernier cas du filtrage n'est pas sensé se produire quand la liste de bits représente bien un arbre, ceci est signalé par assert false qui déclenchera une erreur à l'exécution. On aurait pu aussi omettre ce dernier cas, mais alors le filtrage n'est pas exhaustif, comme le signalerait le compilateur.

File "sol.ml", line 191, characters 21-283:
Warning: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
[]
Laisser ainsi consciemment des avertissements n'est pas une bonne pratique de programmation. Car alors on finira par ignorer les avertissements du compilateur, en passant à côté de vraies erreurs. D'où l'usage de assert false.

Trop de warning tue le warning.

On peut noter que liste_vers_arbre ne prend pas la peine de vérifier que toute la liste l est consommée. C'est bien pratique pour la question suivante.