caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Overriding an entry in a polymorphic variant
@ 2006-08-31 21:58 Yaron Minsky
  2006-08-31 22:04 ` Yaron Minsky
  0 siblings, 1 reply; 3+ messages in thread
From: Yaron Minsky @ 2006-08-31 21:58 UTC (permalink / raw)
  To: Caml Mailing List

[-- Attachment #1: Type: text/plain, Size: 638 bytes --]

Does anyone know if there is a clean way of overriding a field in a
polymorhphic variant.  I want to do something like this:

type bot = [ `bot ]
type top = [`bot | `top]
type t = [ `a of bot | `b of bot | `c of bot | `d of bot | `e of bot ]
type t1 = [ t | `c of top  | `e of top ]

the desired end result being that t1 is actually [ `a of bot | `b of bot |
`c of top | `d of bot | `e of top ].  I'm hoping to do this largely to
enable some phantom-types hackery I'm working on.  I'm not sure it matters
from the point of view of whether this is doable, but it is potentially
relevant that bot is a subtype of top.

Thanks in advance,
y

[-- Attachment #2: Type: text/html, Size: 694 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Overriding an entry in a polymorphic variant
  2006-08-31 21:58 Overriding an entry in a polymorphic variant Yaron Minsky
@ 2006-08-31 22:04 ` Yaron Minsky
  2006-08-31 23:29   ` [Caml-list] " skaller
  0 siblings, 1 reply; 3+ messages in thread
From: Yaron Minsky @ 2006-08-31 22:04 UTC (permalink / raw)
  To: Caml Mailing List

[-- Attachment #1: Type: text/plain, Size: 945 bytes --]

On 8/31/06, Yaron Minsky <yminsky@cs.cornell.edu> wrote:
>
> Does anyone know if there is a clean way of overriding a field in a
> polymorhphic variant.  I want to do something like this:
>
> type bot = [ `bot ]
> type top = [`bot | `top]
> type t = [ `a of bot | `b of bot | `c of bot | `d of bot | `e of bot ]
> type t1 = [ t | `c of top  | `e of top ]
>
> the desired end result being that t1 is actually [ `a of bot | `b of bot |
> `c of top | `d of bot | `e of top ].  I'm hoping to do this largely to
> enable some phantom-types hackery I'm working on.  I'm not sure it matters
> from the point of view of whether this is doable, but it is potentially
> relevant that bot is a subtype of top.
>

Small addendum:  I'm still not sure this is relevant, but I did get my
example slightly backwards.  top should be a subtype of bot, not the other
way.  So the definitions of bot and top should be:

type bot = [ `bot |  `top]
type top = [`top]

[-- Attachment #2: Type: text/html, Size: 1294 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Caml-list] Re: Overriding an entry in a polymorphic variant
  2006-08-31 22:04 ` Yaron Minsky
@ 2006-08-31 23:29   ` skaller
  0 siblings, 0 replies; 3+ messages in thread
From: skaller @ 2006-08-31 23:29 UTC (permalink / raw)
  To: Yaron Minsky; +Cc: Caml Mailing List

On Thu, 2006-08-31 at 18:04 -0400, Yaron Minsky wrote:
> On 8/31/06, Yaron Minsky <yminsky@cs.cornell.edu> wrote:
>         Does anyone know if there is a clean way of overriding a field
>         in a polymorhphic variant.  I want to do something like this:
>         
>         type bot = [ `bot ]
>         type top = [`bot | `top]
>         type t = [ `a of bot | `b of bot | `c of bot | `d of bot | `e
>         of bot ] 
>         type t1 = [ t | `c of top  | `e of top ]
>         
>         the desired end result being that t1 is actually [ `a of bot |
>         `b of bot | `c of top | `d of bot | `e of top ].  I'm hoping
>         to do this largely to enable some phantom-types hackery I'm
>         working on.  I'm not sure it matters from the point of view of
>         whether this is doable, but it is potentially relevant that
>         bot is a subtype of top.
> 
> Small addendum:  I'm still not sure this is relevant, 

It is ..

> but I did get my example slightly backwards.  top should be a subtype
> of bot, not the other way.  So the definitions of bot and top should
> be: 
> 
> type bot = [ `bot |  `top]
> type top = [`top]


Polymorphic variants are covariant in their arguments.
The first version in Ocaml did not support covariant arguments.
The current version does: excuse annotations but I always get
sub and super types mixed up.


(* subtypes have subset of cases *)
type top = [ `bot | `top ] (* super type *)
type bot = [ `bot ]        (* sub type   *)
;;

( `bot : bot :> top ) (* cast from sub to super type adds cases *)
;;

type sub = [ `a of bot | `b of bot | `c of bot | `d of bot ];;

(* same constructor names, but arguments of `c,`d have more cases
  so it is a supertype of sub *)

type super = [ `a of bot | `b of bot | `c of top | `d of top ];;

let c : sub = `c `bot;;

match c with
| `c x -> `c (x: bot :> top)   (* coerce argument *)
| _ -> assert false
;;

( c : sub :> super )     (* directly coerce the type *)
;;


This wasn't your original question, but is the important
part of the answer.

The trivial part is: no you cannot "override" a type constructor:

# type a = [`A of int | `A of string];;
This variant type contains a constructor [ `A of string ] which
should be [ `A of int ]

Within a single type, a constructor can only have one argument
type, and the [ ... ] notation using an alias is just sugar
for the expansion of the alias.

But there is no need: just partition the constructors:

type base = [`a of bot | `b of bot]
type sub = [ base | `c of bot | `d of bot]
type super = [ base | `c of top | `d of top]

If you REALLY want to be sexy, you can make the argument type
parametric:

type 'b ext = [`c of 'b | `d of 'b ]
type sub = [ base | bot ext ]
type super = [ base | top ext ]


-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-08-31 23:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-08-31 21:58 Overriding an entry in a polymorphic variant Yaron Minsky
2006-08-31 22:04 ` Yaron Minsky
2006-08-31 23:29   ` [Caml-list] " skaller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).