I'm currently trying to do some mahjong hand processing in OCaml and straight from the beginning I'm confronted with something that bugs me.
I'll give you examples based on cards because I don't want to confuse anyone with mahjong terminology.
Just like in this part on User-Defined Types from OCaml for the Skeptical, I want to use variant types to describe suits, cards, and everything.
type suit = Club | Diamond | Heart | Spade
type value = Jack | Queen | King | Ace | Num of int
type card = Card of suit * value | Joker
type hand = card list
And it would be really nice if I could write a smart compare
function that would understand ordered variant types.
Ideally I'd write something like that:
type suit = Club < Diamond < Heart < Spade
type value = Num of int < Jack < Queen < King < Ace
type card = Card of suit * value < Joker
type hand = card list
So that when I do
List.sort Pervasives.compare [Card(Diamond, Num 3); Joker; Card(Spade, Ace); Card(Diamond, Num 2)]
it gives me
[Card(Diamond, Num 2); Card(Diamond, Num 3); Card(Spade, Ace); Joker]
Alas, the ocaml toplevel returns
[Joker; Card(Spade, Ace); Card(Diamond, Num 2); Card(Diamond, Num 3)]
(which is already quite good!)
Basically I want a compare
function that would take hints from the type declaration structure.
I've read this article on polymorphic compare and this similar question but I'm not sure I want to depend on compare_val
.
Do I really have to write my own compare function? If you recommend me to write one, do you have tips on the way it should be written, especially to reduce the number of cases?
P.S.: I just heard about deriving(Ord)
in Haskell... Might be enough for me to take the leap...
deriving
sugar. Especially for a type this small. – RemunerateOrd
or write it yourself. With some constructor reordering the derivedOrd
would do what you want. – MurineInteger `Mod` 10
to get numbers modulo10
: hackage.haskell.org/packages/archive/modular-arithmetic/1.0.1.0/…. Another reason to use Haskell :P. – Crumpton