From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 9F0EABC48 for ; Wed, 30 Mar 2005 06:03:33 +0200 (CEST) Received: from vapor.isi.edu (vapor.isi.edu [128.9.64.64]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id j2U3QmPY008031 for ; Wed, 30 Mar 2005 05:26:49 +0200 Received: from albini.isi.edu (albini.isi.edu [128.9.216.111]) by vapor.isi.edu (8.11.6p2+0917/8.11.2) with ESMTP id j2U3Q2s29940 for ; Tue, 29 Mar 2005 19:26:02 -0800 (PST) Date: Tue, 29 Mar 2005 19:26:02 -0800 (PST) From: Hal Daume III To: Caml Mailing List Subject: Re: [Caml-list] generic data type -> int function In-Reply-To: <16963.63456.885441.571929@gargle.gargle.HOWL> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-ISI-4-38-10-MailScanner: Found to be clean X-MailScanner-From: hdaume@isi.edu X-Miltered: at concorde with ID 424A1C78.003 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; caml-list:01 enum:01 mtype:01 pairs:01 mtype:01 pairs:01 filliatre:01 integers:01 constructors:01 integers:01 constructors:01 nam:98 nam:98 ...:98 wrote:01 X-Spam-Checker-Version: SpamAssassin 3.0.2 (2004-11-16) on yquem.inria.fr X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.0.2 X-Spam-Level: Unsatisfied with any of the solutions offered to me, I threw together a quick perl script to do this for me. For anyone who wants it, you can get it at: http://www.isi.edu/~hdaume/type_to_enum.pl It's very limited in that it has no knowledge of built in types, and type specs must all be on one line per type, but for my purposes it works keenly. Example input: type etype = GPE | LOC | ORG | PER | NAE_e | BOS_e type mtype = BAR | NAM | NOM | PRE | PRO | OTHER | NAE_m | BOS_m type pairs = EM of etype*mtype | EE of etype*etype | MM of mtype*mtype type pairs2 = EP of etype * pairs | MP of mtype * pairs Corresponding output: let int_of_etype = function | GPE -> 0 | LOC -> 1 | ORG -> 2 | PER -> 3 | NAE_e -> 4 | BOS_e -> 5 let int_of_mtype = function | BAR -> 0 | NAM -> 1 | NOM -> 2 | PRE -> 3 | PRO -> 4 | OTHER -> 5 | NAE_m -> 6 | BOS_m -> 7 let int_of_pairs = function | EM (etype_0, mtype_1) -> 0 + 1 * (int_of_etype etype_0 + 6 * (int_of_mtype mtype_1)) | EE (etype_0, etype_1) -> 48 + 1 * (int_of_etype etype_0 + 6 * (int_of_etype etype_1)) | MM (mtype_0, mtype_1) -> 84 + 1 * (int_of_mtype mtype_0 + 8 * (int_of_mtype mtype_1)) let int_of_pairs2 = function | EP (etype_0, pairs_1) -> 0 + 1 * (int_of_etype etype_0 + 6 * (int_of_pairs pairs_1)) | MP (mtype_0, pairs_1) -> 888 + 1 * (int_of_mtype mtype_0 + 8 * (int_of_pairs pairs_1)) I've stress tested it a bit and it seems to be all in working order. On Fri, 25 Mar 2005, Jean-Christophe Filliatre wrote: > > Hi, > > > Is there a straightforward way (or a built in function, or...) to > > automatically map an enumerated data type to integers (and back, if > > possible, but that's not strictly necessary). > > I don't think there such a built-in function. But using Obj.magic to > convert constant constructors to integers is safe (the constant > constructors of a type are represented by integers starting from 0): > > ====================================================================== > # type t = A|B|C|D;; > type t = A | B | C | D > # (Obj.magic A : int);; > - : int = 0 > # (Obj.magic D : int);; > - : int = 3 > ====================================================================== > > Going the way back obviously requires a dynamic check (the integer > needs to be within the right bounds). > > Note that I do not encourage the use of Obj.magic. I even think that > writing your own function to convert constructors to integers will be > equally fast (since pattern-matching is compiled using a constant time > lookup table in this case); and you can macro-generate such functions. > > Hope this helps, > -- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume