English version
Accueil     À propos     Téléchargement     Ressources     Contactez-nous    

Ce site est rarement mis à jour. Pour les informations les plus récentes, rendez-vous sur le nouveau site OCaml à l'adresse ocaml.org.

Browse thread
help with open vs closed polymorphic variants
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2008-03-16 (04:15)
From: Erick Tryzelaar <idadesub@u...>
Subject: help with open vs closed polymorphic variants
I'm not sure if this is the right term for describing polymorphic
variants, but it seems to me that there are two ways to work with a
complex hierarchy of polymorphic types to get something that's similar
to inheritance. First is to use what I call closed variants, where you
build the tree bottom up like this:

type foo2 = [`Foo2];;
type foo = [foo2 | `Foo];;
type bar = [`Bar];;
type baz = [`Baz];;
type value = [foo|bar|baz];;

The open variants are the other way around:

type value = [`value];;
type foo = [value|`Foo];;
type bar = [value|`Bar];;
type baz = [value|`Baz];;
type foo2 = [foo|`Foo2];;

These both let you call a function on a subset of variants. For closed
variants, you can do:

type 'a t = T of 'a;;
let f (x:[< foo] t) = ();;
f (T (`Foo :> foo));;
f (T (`Foo2 :> foo2));;

but this is a type error: "f (T (`Bar :> bar))". Likewise with open variants:

type 'a t = T of 'a;;
let f (x:[> `Foo] t) = ();;
f (T (`Foo :> foo));;
f (T (`Foo2 :> foo2));;

With "f (T (`Bar :> bar))" being an error as well. However, say we
wanted to allow for a function that works on two subsets of variant
tree. I can do this with closed variants:

let f (x:[< foo|bar] t) = ();;
f (T (`Foo :> foo));;
f (T (`Foo2 :> foo2));;
f (T (`Bar :> bar));;

But now "f (T (`Baz :> baz))" is a type error. However, I can't figure
out if there's an equivalent with open variants. The naive solution
doesn't work:

# let f (x:[< `Foo|`Bar] t) = ();;
# f (make_foo ());;
This expression has type foo t but is here used with type ([< `Foo ] as 'a) t
Type foo = [ `Foo | `value ] is not compatible with type 'a
The second variant type does not allow tag(s) `value

It doesn't even type the first call. Is this impossible?