Précédent Index Suivant

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.






Précédent Index Suivant