Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is an elegant idiom for a lexicographic Ord instance?

This code works, but it's verbose, and I'm sure there's a more concise way.

import qualified Data.Vector as V

data Event a = Event { start :: Time
                     , duration :: Time
                     , payload :: Maybe a } deriving (Show, Eq)

instance Ord a => Ord (Event a) where
  (<=) a b = start a < start b
    || start a == start b && duration a < duration b
    || start a == start b && duration a == duration b && payload a <= payload b

The idea behind it is that if one thing starts before the other, you should call it the lesser, and don't even look at the other two fields. Similarly, if they start at the same time but one is more brief, then that briefer one is the lesser, and you can ignore the third field.

like image 410
Jeffrey Benjamin Brown Avatar asked Dec 11 '22 08:12

Jeffrey Benjamin Brown


1 Answers

Use deriving:

data Event a = Event { start :: Time
                     , duration :: Time
                     , payload :: Maybe a } deriving (Show, Eq, Ord)

The derived instance is automatically lexicographic.

like image 193
HTNW Avatar answered Feb 20 '23 13:02

HTNW