From: "Lukasz Stafiniak" <lukstafi@gmail.com>
> Thank you for the answer. Let's play the dual of this game:
>
> # type 'a sty = [`Foo of (int * 'a) sty | `Bar];;
> Characters 4-45:
> type 'a sty = [`Foo of (int * 'a) sty | `Bar];;
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> In the definition of sty, type (int * 'a) sty should be 'a sty
> # type 'a nty = Foo of (int * 'a) nty | Bar;;
> type 'a nty = Foo of (int * 'a) nty | Bar
Indeed, this is to be expected. Again, if one needs both polymorphic
variants and irregular types, it is possible to combine both, but not
very natural.
> (I wonder if this is the reason when people rant that structural types
> are a weaker form of type control... ;) Recently I've started using
> closed polymorphic variant types to build subtyping hierarchies and
> this gives more type control to me, I think.)
For your first point, I don't think so. Irregular types are quite rare
in practice, though they arise rather naturally when combining objects
and polymorphism. What some people do not like about structural types
is that they do not "brand" types: you can define the same type
elsewhere, possibly with a different intended meaning, and the
compiler will not distinguish between the two. This type equality also
means that you cannot rely on type identity for privacy features: this
is the reason why ocaml private methods are not like Java.
But on the other hand, in many cases you precisely want this equality.
Jacques Garrigue