caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Berke Durak <berke.durak@exalead.com>
To: Damien Guichard <alphablock@orange.fr>,
	Caml-list List <caml-list@inria.fr>
Subject: Re: [Caml-list] Variants & structural ordering
Date: Tue, 05 Feb 2008 10:47:32 +0100	[thread overview]
Message-ID: <47A830B4.8080801@exalead.com> (raw)
In-Reply-To: <20080205081845.2D24D1C02531@mwinf2341.orange.fr>

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


  reply	other threads:[~2008-02-05  9:47 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-05  8:21 Damien Guichard
2008-02-05  9:47 ` Berke Durak [this message]
2008-02-05  9:48 ` [Caml-list] " Oliver Bandel
2008-02-05 15:04 ` Jon Harrop
2008-02-06  8:21 ` Michaël Grünewald
2008-02-07 15:50 ` Damien Doligez
2008-02-05 16:59 Damien Guichard
2008-02-05 17:25 ` Stéphane Lescuyer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47A830B4.8080801@exalead.com \
    --to=berke.durak@exalead.com \
    --cc=alphablock@orange.fr \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).