From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: * X-Spam-Status: No, score=1.0 required=5.0 tests=AWL,MSGID_MULTIPLE_AT autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 1E2B4BC37 for ; Fri, 29 May 2009 16:43:23 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoACAFORH0pRZ90vlGdsb2JhbACXCoELAQEBAQkLCAkRA7kUhAwF X-IronPort-AV: E=Sophos;i="4.41,272,1241388000"; d="scan'208";a="40787823" Received: from mtaout01-winn.ispmail.ntl.com ([81.103.221.47]) by mail4-smtp-sop.national.inria.fr with ESMTP; 29 May 2009 16:43:22 +0200 Received: from aamtaout03-winn.ispmail.ntl.com ([81.103.221.35]) by mtaout01-winn.ispmail.ntl.com (InterMail vM.7.08.04.00 201-2186-134-20080326) with ESMTP id <20090529144322.IJBR6742.mtaout01-winn.ispmail.ntl.com@aamtaout03-winn.ispmail.ntl.com>; Fri, 29 May 2009 15:43:22 +0100 Received: from romulus.metastack.com ([81.102.132.77]) by aamtaout03-winn.ispmail.ntl.com (InterMail vG.2.02.00.01 201-2161-120-102-20060912) with ESMTP id <20090529144322.CWTX2093.aamtaout03-winn.ispmail.ntl.com@romulus.metastack.com>; Fri, 29 May 2009 15:43:22 +0100 Received: from COUNTERTENOR (dynamic90.vpdn.csx.cam.ac.uk [131.111.7.90]) (authenticated bits=0) by romulus.metastack.com (8.14.2/8.14.2) with ESMTP id n4TEhGNT012108 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO); Fri, 29 May 2009 15:43:18 +0100 From: "David Allsopp" To: "'Dario Teixeira'" Cc: "'OCaml List'" References: <327446.80988.qm@web111511.mail.gq1.yahoo.com> In-Reply-To: <327446.80988.qm@web111511.mail.gq1.yahoo.com> Subject: RE: [Caml-list] Width subtyping Date: Fri, 29 May 2009 16:43:14 +0200 Message-ID: <000301c9e06b$ce22a7f0$6a67f7d0$@allsopp@metastack.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Mailer: Microsoft Office Outlook 12.0 Thread-Index: AcngZzOtb9/z0RxuQse79NSLsHdcKQAAxv+w Content-Language: en-gb Organization: MetaStack Solutions Ltd. X-Scanned-By: MIMEDefang 2.65 on 81.102.132.77 X-Cloudmark-Analysis: v=1.0 c=1 a=bXPR0s6Z1s0N4pvnaHQA:9 a=HUp1tMXEdcJ2Y3alSXQA:7 a=281cL97N8eOyxtsp3yzCTfwITyEA:4 X-Spam: no; 0.00; subtyping:01 model:01 subtyping:01 ocaml:01 sig:01 val:01 val:01 struct:01 variants:01 polymorphic:01 caml-list:01 functions:01 constructor:01 int:01 int:01 > Though it is probably been-there-done-that material for the veterans = in > this list, for the sake of the not-so-veterans I have to ask: how do = you guys > typically model width subtyping in Ocaml? Definitely not a veteran, but might private types help a little? > Consider for example three record types that share some of their = fields: >=20 > type t1 =3D {a: int; b: int; c: int; } > type t2 =3D {a: int; b: int; c: int; d: int;} > type t3 =3D { b: int; c: int; d: int;} Modelled as... module M : sig type t' =3D {a: int; b: int; c: int; d: int} type t =3D private T1 of t' | T2 of t' | T3 of t' val makeT1 : int -> int -> int -> t val makeT2 : int -> int -> int -> int -> t val makeT3 : int -> int -> int -> t end =3D struct type t' =3D {a: int; b: int; c: int; d: int} type t =3D T1 of t' | T2 of t' | T3 of t' let makeT1 a b c =3D T1 {a =3D a; b =3D b; c =3D c; d =3D 0} let makeT2 a b c d =3D T2 {a =3D a; b =3D b; c =3D c; d =3D d} let makeT3 b c d =3D T3 {a =3D 0; b =3D b; c =3D c; d =3D d} end This way you're always dealing with the same product type, but the sum = type tells you which fields are actually valid. Of course, it relies on = there being an obvious sentinel value for unused fields (otherwise you = just end up with 'a option everywhere) and I still don't think it's that = neat as you can still match against fields which aren't valid but at = least the type system prevents you from being handed an illegal value. = The benefit is that you don't need special "get" functions (just a match = on type t to extract the t' value from each constructor). I can't get my = head around how private polymorphic variants work to see if they can = refine this further... David