Option -rectypes
Author: Christian.Queinnec@lip6.fr

## Option `-rectypes`

Il existe une option du compilateur et de la boucle d'interaction qui permet de lever cette limitation aux objets des types cycliques.

    $ ocamlc -rectypes  ...
    $ ocamlopt -rectypes  ...
    $ ocaml -rectypes

Si nous reprenons les exemples précédents dans une boucle d'interaction lancée avec cette option, voici ce qu'on obtient.

    # type 'a arbre = 'a * 'a arbre list ;;
    type 'a arbre = 'a * 'a arbre list

    # let rec hauteur = function
         (_,[]) -> 1
       | (_,fils) -> 1 + (max_list (List.map hauteur fils)) ;;
    val hauteur : ('b * 'a list as 'a) -> int = <fun>

Les valeurs `arbre_1`, `arbre_2` et `arbre_3` définies auparavant n'ont pas le même type mais ont toutes un type compatible avec celui de `hauteur`.

    # hauteur arbre_1 ;;
    - : int = 1
    # hauteur arbre_2 ;;
    - : int = 2
    # hauteur arbre_3 ;;
    - : int = 3

Le mot clé as fait partie du langage de type, à ce titre il peut être utilisé dans une déclaration de type.

### Syntaxe

type nom = typedef as 'var ;;

Nous pouvons définir le type arbre en utilisant cette syntaxe.

    # type 'a arbre = ( 'a * 'sommet list ) as 'sommet ;;
    type 'a arbre = 'a * 'a arbre list

### Warning

Si ce mode peut se révéler utile en quelques occasions, il a tendance à accepter le typage de trop de valeurs en leur donnant des types difficiles à lire.

Sans l'option `-rectypes`, la fonction suivante aurait été rejetée par le typeur.

    # let inclus l1 l2 =
       let rec mem x = function
           [] -> false
         | a::l -> (l=x) || (mem x a) (* erreur volontaire : inversion de a et l *)
       in List.for_all (fun x -> mem x l2) l1  ;;
    val inclus : ('a list as 'a) list list -> ('b list as 'b) -> bool = <fun>

Bien que l'examen du type permet de constater immédiatement qu'il y a une erreur, il n'y a plus de message d'erreur permettant de localiser cette erreur.