Ord
異なる順序でソートするためだけに複数のインスタンスを定義する必要はありません。sortBy
明示的な比較関数を引数として取る関数を使用するだけです。
巧妙なトリック: レコード型を使用して型を定義する場合Person
、 import Data.Function
(on
関数を提供します) およびData.Monoid
、いくつかの巧妙なトリックを使用して、これをより簡潔かつ簡単にすることができます。
import Data.Function (on)
import Data.Monoid (mappend)
import Data.List (sortBy)
data Person = Person { firstName :: String, lastName :: String }
instance Show Person where
show p = firstName p ++ " " ++ lastName p
exampleData = [ Person "Mary" "Smith"
, Person "Joe" "Smith"
, Person "Anuq" "Katig"
, Person "Estanislao" "Martínez"
, Person "Barack" "Obama" ]
--
-- The "on" function allows you to construct comparison functions out of field
-- accessors:
--
-- compare `on` firstName :: Person -> Person -> Ordering
--
-- That expression evaluates to something equivalent to this:
--
-- (\x y -> compare (firstName x) (firstName y))
--
sortedByFirstName = sortBy (compare `on` firstName) exampleData
sortedByLastName = sortBy (compare `on` lastName) exampleData
--
-- The "mappend" function allows you to combine comparison functions into a
-- composite one. In this one, the comparison function sorts first by lastName,
-- then by firstName:
--
sortedByLastNameThenFirstName = sortBy lastNameFirstName exampleData
where lastNameFirstName =
(compare `on` lastName) `mappend` (compare `on` firstName)