Say I have a data type like the following:
data Foo = Foo { field1, field2, field3 :: Int }
And I'd like to make it an instance of Ord
by comparing field1
, field2
, and field3
in a particular order.
I find it very annoying to write:
-- (we need Eq Foo to define Ord Foo)
instance Eq Foo where
x == y = all id [ f x == f y
| f <- [field1, field2, field3] ]
instance Ord Foo where
compare x y = case (comparing field1) x y of
EQ -> case (comparing field2) x y of
EQ -> (comparing field3) x y
ord -> ord
ord -> ord
Monads like Maybe
and Either
have some really nice support for this kind of thing, and I find myself wishing that Ordering
had something similar, e.g.
instance Ord Foo where
compare == comparing field1 >>= comparing field2 >>= comparing field3
...or something like that.
I've needed to do this for complex data types, where re-ordering fields in the definition and depending on default definitions for deriving (Eq, Ord)
were not possible, so I'm not interested in solutions that game the default instance declarations.
Is there a more elegant, or at least more terse, way to define this kind of ordering?
Thanks!