Option -rectypes
With a compiler option, we can avoid this restriction to objects in cyclic
types.
$ ocamlc -rectypes ...
$ ocamlopt -rectypes ...
$ ocaml -rectypes
If we take up the above examples in a toplevel started with this option, here is
what we get.
# type
'a
tree
=
'a
*
'a
tree
list
;;
type 'a tree = 'a * 'a tree list
# let
rec
height
=
function
(_,[]
)
->
1
|
(_,
sons)
->
1
+
(max_list
(List.map
height
sons))
;;
val height : ('b * 'a list as 'a) -> int = <fun>
The values tree_1, tree_2 and tree_3
previously defined don't have the same type, but they all have a type
compatible with that of height.
# height
tree_1
;;
- : int = 1
# height
tree_2
;;
- : int = 2
# height
tree_3
;;
- : int = 3
The keyword as belongs to the type language, and as such, it can be
used in a type declaration.
Syntax
type nom = typedef as 'var ;;
We can use this syntax to define type tree.
# type
'a
tree
=
(
'a
*
'vertex
list
)
as
'vertex
;;
type 'a tree = 'a * 'a tree list
Warning
If this mode may be useful in some cases, it tends to accept the typing of too
many values, giving them types that are not easy to read.
Without the option -rectypes, the function below would have been rejected
by the typing system.
# let
inclus
l1
l2
=
let
rec
mem
x
=
function
[]
->
false
|
a::l
->
(l=
x)
||
(mem
x
a)
(* an error on purpose: a and l inverted *)
in
List.for_all
(fun
x
->
mem
x
l2)
l1
;;
val inclus : ('a list as 'a) list list -> ('b list as 'b) -> bool = <fun>
Although a quick examination of the type allows to conclude to an error, we no
longer have an error message to help us locating this error.