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=0.0 required=5.0 tests=none autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id BBF27BC6C for ; Tue, 5 Feb 2008 10:47:36 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAGK/p0fAXQInh2dsb2JhbACQKgEBAQgKKYEVmwE X-IronPort-AV: E=Sophos;i="4.25,306,1199660400"; d="scan'208";a="7610219" Received: from concorde.inria.fr ([192.93.2.39]) by mail1-smtp-roc.national.inria.fr with ESMTP; 05 Feb 2008 10:47:36 +0100 Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id m159lUo5025264 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Tue, 5 Feb 2008 10:47:36 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAOq+p0fBL1AZh2dsb2JhbACQKgEBAQgKKYEVmwA X-IronPort-AV: E=Sophos;i="4.25,306,1199660400"; d="scan'208";a="8764132" Received: from gw.exalead.com (HELO exalead.com) ([193.47.80.25]) by mail3-smtp-sop.national.inria.fr with ESMTP; 05 Feb 2008 10:47:35 +0100 Received: from [192.168.204.148] (madpc064.exalead.com [192.168.204.148]) (authenticated bits=0) by exalead.com (8.14.0/8.14.0) with ESMTP id m159lWEo029013; Tue, 5 Feb 2008 10:47:34 +0100 Message-ID: <47A830B4.8080801@exalead.com> Date: Tue, 05 Feb 2008 10:47:32 +0100 From: Berke Durak User-Agent: Thunderbird 1.5.0.10 (X11/20070221) MIME-Version: 1.0 To: Damien Guichard , Caml-list List Subject: Re: [Caml-list] Variants & structural ordering References: <20080205081845.2D24D1C02531@mwinf2341.orange.fr> In-Reply-To: <20080205081845.2D24D1C02531@mwinf2341.orange.fr> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit X-Miltered: at concorde with ID 47A830B3.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; berke:01 durak:01 berke:01 durak:01 variants:01 damien:01 guichard:01 ocaml:01 work-around:01 bug:01 constructors:01 integers:01 constructors:01 ad-hoc:01 ocaml:01 Damien Guichard a écrit : > Hi everybody, Hello > Typically, when you declare: > > type card = > | Card of int > | Jack > | Queen > | King > | Ace > ;; > > The relation you wish is: > > Card(2) < ...< Card(10) < Jack < Queen < King < Ace > > And that's what you get when using F#. Thanks for this bit of knowledge about F#. > However when using OCaml here is what you get: > > Jack < Queen < King < Ace < Card(2) < ...< Card(10) > > And the work-around is: > > type card = > | Card of int > | Jack of unit > | Queen of unit > | King of unit > | Ace of unit > ;; > > Is this a bug or a feature ? Neither: You are not supposed to assume anything on the way compare orders non-primitive types. Constructors without arguments are represented as integers, which, as primitive types, come before blocks, which are used to represent the values of constructors with arguments. The "compare" functions give an ad-hoc order, the only guarantee being that it will be a good ordering. I think you can safely assume that it won't change accross Ocaml releases (unless you start using a new VM.) In practice, people often assume that the components of tuples and records are compared in the same order as their components are given. Relying on the order of enumerated types is more risky: you provide a good example of this. > Will it change in a foreseable future ? I really don't think so and even if it did, there is no reason why it would change in the way that would be useful to you in that particular case, and even then, it would be risky to depend on that behaviour, and, besides, what's the point? Simply use something like: let max_card = 10 let int_of_card = function | Card n -> assert(n < max_card); n | Jack -> max_card | Queen -> max_card + 1 | King -> max_card + 2 let compare c1 c2 = compare (int_of_card c1) (int_of_card c2) -- Berke DURAK