What is an elegant idiom for a lexicographic instance of Ord?

This code works, but it is verbose, and I'm sure there is 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 is that if one thing starts earlier than the other, you should call it less and don't even look at the other two fields. Similarly, if they start at the same time, but one is shorter, then this one is shorter than less, and you can ignore the third field.

+4
source share
3 answers

@HTNW, Ord . , , Ord, Ord :

instance Ord a => Ord (Event a) where
  (<=) a b = order a <= order b
    where order x = (start x, duration x, payload x)
+4

deriving:

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

.

+6

HTNW, deriving, . (, ), compare ( comparing, ), (<=), Monoid Ordering, :

import Data.Ord (comparing)
import Data.Monoid ((<>))

instance Ord a => Ord (Event a) where
    compare a b = comparing start a b
        <> comparing duration a b
        <> comparing payload a b

Monoid, , :

instance Ord a => Ord (Event a) where
    compare = comparing start <> comparing duration <> comparing payload
+3

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


All Articles