caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: skaller <skaller@users.sourceforge.net>
To: Yaron Minsky <yminsky@cs.cornell.edu>
Cc: Caml Mailing List <caml-list@inria.fr>
Subject: Re: [Caml-list] Re: Overriding an entry in a polymorphic variant
Date: Fri, 01 Sep 2006 09:29:11 +1000	[thread overview]
Message-ID: <1157066951.6860.84.camel@rosella.wigram> (raw)
In-Reply-To: <891bd3390608311504g13cf0ea6x2cbb0a79cfd29760@mail.gmail.com>

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


      reply	other threads:[~2006-08-31 23:29 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-31 21:58 Yaron Minsky
2006-08-31 22:04 ` Yaron Minsky
2006-08-31 23:29   ` skaller [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1157066951.6860.84.camel@rosella.wigram \
    --to=skaller@users.sourceforge.net \
    --cc=caml-list@inria.fr \
    --cc=yminsky@cs.cornell.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).