On 2012/02/13, at 2:36, Gabriel Scherer wrote:

> Thank you, Jacques and Jeremy, for the examples. Indeed that looks quite 
> subtle.
> 
> I found it helpful to write an informal proof of covariance of the
> following type:
> 
>  type +_ expr =
>    | Val : 'a -> 'a expr
>    | Prod : 'a expr * 'b expr -> ('a * 'b) expr
> 
> Or, in a more explicit formulation using imaginary syntax with
> explicit existential variables and equalities.
> 
>  type +'a expr =
>    | Val of 'b . 'b with ('a = 'b)
>    | Prod of 'b 'c. 'b expr * 'c expr with ('a = 'b * 'c)
> 
> The informal proof goes as follow: assuming α ≤ α', we wish to show
> that α expr ≤ β expr. For a given (t : α expr):
>  - if (t) is (Val (v : α)), then by α ≤ α' we have (v : α') so (Val v
> : α' expr)
>  - if (t) is Prod((t1 : β expr), (t2 : γ expr)), with (α = β * γ), then
>    we have (β * γ ≤ α'). *By inversion* we know that there must exist
> β', γ' with
>    α' = β' * γ', β ≤ β' and γ ≤ γ'. We therefore have (t1 : β' expr),
> (t2 : γ' expr),
>    and therefore (Prod(t1,t2) : α' expr)
> 
> The core of the proof is an inversion lemma for subtyping at product types:
>    if β*γ ≤ α' then α' is of the form β'*γ' with β≤β', γ≤γ'
> 
> The strength of the inversion lemma depends a lot on the details of
> the theory. For example, if α = int and α ≤ α', do we have α' = int?
> And if α ≥ α'? I believe the answer to the α ≤ α' case is "yes", which
> would make the (type +_ expr = Const : int -> int expr) case correctly
> covariant, but as Jacques showed the answer is no in the contravariant
>  case α ≥ α', we have (int ≥≠ private int).

[...]

> I'm going to think a bit more about this. What do you think of the
> "proof" in the Prod case? Is there such an inversion principle for the
> OCaml type theory?

The proof looks fine.
Subtyping in OCaml has not been much studied.
You can find a short draft attempting to specify the current behavior
on my publication page.
Again I wonder whether you are not going to get problems with abstraction.
At first sight, no: if when you define a GADT t, the type u is abstract, then
it will have no supertype in any environment where we use t.
But if you think more carefully, you realize that if in the future we allow
(gadt-)unification between abstract types, everything breaks, since abstract
types may end up having supertypes in a local environment.
So it looks like the only types you can allow for instantiation are concrete
datatypes and well-known types (abstract types defined in the initial 
environment
or in the current module).

Jacques Garrigue

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa-roc.inria.fr/wws/info/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

Reply via email to