Let’s say that I have the following code:
import Data.List.Ordered
data Person = Person String String
deriving (Show, Eq)
main :: IO ()
main = print . show . sort $ [(Person "Isaac" "Newton"), (Person "Johannes" "Kepler")]
And in the same module, I want to be able to sort the list by both first name and by last name. Obviously I can’t do this:
instance Ord Person where
compare (Person _ xLast) (Person _ yLast) = compare xLast yLast
instance Ord Person where
compare (Person xFirst _) (Person yFirst _) = compare xFirst yFirst
So, what are my options?
This page mentions “You can achieve this by wrapping the type in a newtype and lift all required instances to that new type.” Can someone give an example of that?
Is there a better way?
The newtype method would be:
Then the sorting function would be something like:
and similarly for
ByLastname.A better way is to use
sortBy,compareandon, with functions for retrieving the first and last names. i.e.(On that note, it might be worth using a record type for
Person, i.e.data Person = Person { firstName :: String, lastName :: String }, and one even gets the accessor functions for free.)