Browse thread
help with open vs closed polymorphic variants
- Erick Tryzelaar
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| 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?