From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 4B982BCBE for ; Fri, 1 Sep 2006 01:29:31 +0200 (CEST) Received: from smtp1.adl2.internode.on.net (smtp1.adl2.internode.on.net [203.16.214.181]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id k7VNTSBZ031190 for ; Fri, 1 Sep 2006 01:29:30 +0200 Received: from rosella (ppp14-47.lns2.syd7.internode.on.net [59.167.14.47]) by smtp1.adl2.internode.on.net (8.13.6/8.13.5) with ESMTP id k7VNTBqC034388; Fri, 1 Sep 2006 08:59:12 +0930 (CST) (envelope-from skaller@users.sourceforge.net) Subject: Re: [Caml-list] Re: Overriding an entry in a polymorphic variant From: skaller To: Yaron Minsky Cc: Caml Mailing List In-Reply-To: <891bd3390608311504g13cf0ea6x2cbb0a79cfd29760@mail.gmail.com> References: <891bd3390608311458v5de0651qd8a38a896c77c72d@mail.gmail.com> <891bd3390608311504g13cf0ea6x2cbb0a79cfd29760@mail.gmail.com> Content-Type: text/plain Date: Fri, 01 Sep 2006 09:29:11 +1000 Message-Id: <1157066951.6860.84.camel@rosella.wigram> Mime-Version: 1.0 X-Mailer: Evolution 2.6.1 Content-Transfer-Encoding: 7bit X-Miltered: at concorde with ID 44F770D8.001 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; overriding:01 yaron:01 minsky:01 yaron:01 minsky:01 yminsky:01 overriding:01 hackery:01 doable:01 subtype:01 subtype:01 variants:01 ocaml:01 annotations:01 subtypes:01 On Thu, 2006-08-31 at 18:04 -0400, Yaron Minsky wrote: > On 8/31/06, Yaron Minsky 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 Felix, successor to C++: http://felix.sf.net