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=2.0 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE, DNS_FROM_RFC_POST,DNS_FROM_RFC_WHOIS 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 DF83DBBAF for ; Wed, 21 Jan 2009 20:11:16 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AlQEAJbhdklDww/TkWdsb2JhbACOa4UQAQEBAQkLCgcRA6hGkG0FAgGFcIRV X-IronPort-AV: E=Sophos;i="4.37,301,1231110000"; d="scan'208";a="34086982" Received: from web111514.mail.gq1.yahoo.com ([67.195.15.211]) by mail4-smtp-sop.national.inria.fr with SMTP; 21 Jan 2009 20:11:15 +0100 Received: (qmail 83000 invoked by uid 60001); 21 Jan 2009 19:11:14 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com; h=X-YMail-OSG:Received:X-Mailer:Date:From:Subject:To:Cc:In-Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-ID; b=I8Mw5nRFatz9DJv8gBEBozh3mXfpgs05C8H4GeIoAkIrIAloFEGxlyZnYAut+sA+m7Jy0oEHv5IBWnnVBNkNqiSnC2OclH37nNzZr8qBDKd3m8hrm7HDFJPuD/K6XjLNJOs+DVAg99pVGabDOYMVyj6Q90gm/AdXujAwS0ECHJo=; X-YMail-OSG: CY6lo_8VM1lITMNIZ0Z9MGUi_wfyNQhdVLbe0on0CMGOMqIwzFD0puivhX7spt.FsVl74exVJ6CDodbJ.2dviB7_7asO4fr1bwc.V76O65lQqWUrTjGJYqIAOC.jOYFrc6pw4GWyVAvwb9OjcNRGzHf9r0BGPS3uqN5k2U6VQNhI3s5jrlzAzhmInzVGgQ-- Received: from [213.205.71.62] by web111514.mail.gq1.yahoo.com via HTTP; Wed, 21 Jan 2009 11:11:14 PST X-Mailer: YahooMailWebService/0.7.260.1 Date: Wed, 21 Jan 2009 11:11:14 -0800 (PST) From: Dario Teixeira Subject: Re: [Caml-list] Private types in 3.11, again To: Jacques Garrigue Cc: caml-list@yquem.inria.fr In-Reply-To: <20090121.222217.31602828.garrigue@math.nagoya-u.ac.jp> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Message-ID: <361979.82701.qm@web111514.mail.gq1.yahoo.com> X-Spam: no; 0.00; ocaml:01 abbreviation:01 variants:01 model:01 model:01 variants:01 node:01 non-trivial:01 node:01 sig:01 val:01 val:01 struct:01 seq:01 seq:01 Hi, Thank you very much for your help, Jacques! It's always enlightening to see an Ocaml ninja in action, though I'm still digesting the finer points of your message. Anyway, I have implemented all three solutions you sugges= ted: a) Using a private row and PV b) Using a private abbreviation and PV c) Using the mapper + object system with regular variants Solution a) is by far the most convenient, though I'm still having some tro= uble with it (more below). Which brings me to a crucial point where I'm still fuzzy. My initial model for the link-nodes-shall-not-be-ancestors-of-their= -kin problem did indeed rely on what I now realise are GADTs. I ran into a limitation of the type system and so I recast the model using phantom types because I hoped they could provide a workaround. So my question is whether= it is at all possible to emulate GADTs using only PV + phantom types, or if on= the contrary one needs to use the object system in these cases, as exemplified = by solution c). In other words, is solution a) futile, or did you use the obj= ect system in solution c) simply because you were also using regular variants? As for the problem with solution a), it shows up when I implement outside of module Node any non-trivial function operating on 'a Node.t. Function capitalise_node, for example: module Node: sig =09type 'a node_t =3D =09=09[ `Text of string =09=09| `Bold of 'a list =09=09| `Href of string =09=09| `Mref of string * 'a list =09=09] =09type +'a t =3D private [< 'b node_t ] as 'b =09val text: string -> [> `Nonlink ] t =09val bold: 'a t list -> 'a t =09val href: string -> [> `Link ] t =09val mref: string -> [< `Nonlink ] t list -> [> `Link ] t end =3D struct =09type 'a node_t =3D =09=09[ `Text of string =09=09| `Bold of 'a list =09=09| `Href of string =09=09| `Mref of string * 'a list =09=09] =09type +'a t =3D 'b node_t as 'b =09let text txt =3D `Text txt =09let bold seq =3D `Bold seq =09let href lnk =3D `Href lnk =09let mref lnk seq =3D `Mref (lnk, seq) end module Foobar: sig =09val capitalise_node: 'a Node.t -> 'a Node.t end =3D struct =09let capitalise_node node =3D =09=09let rec capitalise_node_aux forbid_link node =3D match (forbid_link, = node) with =09=09=09| (_, `Text txt)=09=09-> Node.text (String.capitalize txt) =09=09=09| (x, `Bold seq)=09=09-> Node.bold (List.map (capitalise_node_aux = x) seq) =09=09=09| (false, `Href lnk)=09=09-> Node.href lnk =09=09=09| (false, `Mref (lnk, seq))=09-> Node.mref lnk (List.map (capitali= se_node_aux true) seq) =09=09=09| _=09=09=09=09-> failwith "this shouldn't happen" =09=09in capitalise_node_aux false node end The code above produces the compiler error below (though remember that this same function works fine inside the Node module): Error: This expression has type ([> `Link | `Nonlink ] as 'a) Node.t list but is here used with type ([< `Nonlink ] as 'b) Node.t list Type 'a Node.t =3D [< `Bold of 'a Node.t list | `Href of string | `Mref of string * 'a Node.t list | `Text of string ] is not compatible with type 'b Node.t =3D [< `Bold of 'b Node.t list | `Href of string | `Mref of string * 'b Node.t list | `Text of string ] The first variant type does not allow tag(s) `Link Thanks again for all your time! Best regards, Dario Teixeira =0A=0A=0A