How to implement "Ord" for algebraic data types in Haskell?

Imagine you have a rating, for example

Rating = OneStar | TwoStars | ThreeStars | FourStars | FiveStars 

What is the best way to initialize / implement "Ord" for this type of algebraic data in Haskell?

+7
source share
3 answers

A better way would be to simply add deriving (Eq, Ord) to the type definition.

Since you specified your constructors in ascending order, the derived instance of Ord will give you exactly the order you want.

However, if the change of order in the definition is not for any reason, you can still get Eq, since the order does not matter for this. Given an Eq instance, we can manually write an instance for Ord. The shortest way to define a comparison would probably be to describe all the combinations for which the comparison should return LT, and then just use compare xy | x == y = Eq; compare _ _ = GT for the rest of the combinations.

+15
source

As already mentioned, you can get Eq and Ord . Or you can get Enum and then do

 instance Eq Rating where x == y = fromEnum x == fromEnum y 

Or just spell it all

 instance Eq Rating where OneStar == OneStar = True TwoStar == TwoStar = True ... _ == _ = False 
+3
source

For those interested, here is a complete, explicit, standard implementation:

The use of Roman numerals.
Use case for readability.

 data RN = I | II | III | IV | V instance Eq RN where I == I = True I == _ = False II == II = True II == _ = False III == III = True III == _ = False IV == IV = True IV == _ = False V == V = True V == _ = False instance Ord RN where compare I x = case x of I -> EQ _ -> LT compare II x = case x of I -> GT II -> EQ _ -> LT compare III x = case x of I -> GT II -> GT III -> EQ _ -> LT compare IV x = case x of V -> LT IV -> EQ _ -> GT compare V x = case x of V -> EQ _ -> GT 
0
source

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


All Articles