Ordered Option Types and Subtypes in OCaml

I am currently trying to do mahjong processing in OCaml, and from the very beginning I come across something that hurts me.

I will give examples based on cards, because I do not want to confuse anyone with the terminology of mahjong.

As in this part of the OCaml User-Defined Types for the skeptic , I want to use type options to describe costumes, cards, and that’s it.

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 very nice if I could write a smart compare function that understands the ordered variants of options.

Ideally, I would write something like this:

 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 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, ocaml toplevel returns

 [Joker; Card(Spade, Ace); Card(Diamond, Num 2); Card(Diamond, Num 3)] 

(this is already good!)

Basically, I want a compare function that will display tooltips from a type declaration structure.

I read this article about polymorphic comparison and this similar question, but I'm not sure I want to depend on compare_val .

Do I need to write my own comparison function? If you recommend me write one, do you have tips on how this should be written, especially to reduce the number of cases?

PS: I just heard about deriving(Ord) in Haskell ... Maybe I should stop jumping ...

+6
source share
1 answer

Yes you need. But you can skip where the polymorphic comparison fits your needs. For example, you do not need to write your comparison for a costume.

The conclusion of Haskell (Ord) is similar to polymorphic comparison: if you can order constructors in ordering in your mind, you can get a comparison function. But it is more powerful as you can create automatic and custom comparison functions. A polymorphic comparison of OCaml cannot do this. For instance,

 type t = ... let compare_t = .... (* custom comparison for t *) type t2 = A of t | B of t | C of t (* I want to write a comparion for t2 now! *) 

If the polymorphic comparison order of constructor A, B, and C meets your needs, you cannot use it to compare t2, since it cannot invoke a custom comparison for t. Therefore, in this case, if I were you, I would write compare_t2 manually. For your example cards too, this is easy to do in 3 minutes.

If your data types are huge and it is very painful to write down all comparisons with your hand, you can automatically generate comparison functions from the type definition using CamlP4 and type_conv, as the conclusion (Ord) concludes. But I'm afraid there is no type_conv module that Ord will show. Personally, I never felt the need to have it. This should be a good exercise for P4 students.

+8
source

Source: https://habr.com/ru/post/947567/


All Articles