I know that the program can sort the list by Mfg or by Year(descending). That is defined on line 9 and 10. But what exactly is the code doing? What is (<>)?
import Data.Semigroup ((<>))
import Data.List (sort, sortOn)
import Data.Ord (comparing)
data Vehicle = Vehicle { mfg :: String, year :: Int } deriving (Eq, Show)
mycars =[Vehicle "Saab" 2000, Vehicle "Volvo" 1995]
instance Ord Vehicle where
compare = flip (comparing year) <> comparing mfg
main = do
print $ sortOn mfg mycars
print $ sort mycars
import Data.Semigroup ((<>))
doesn't do anything useful in your program, and hasn't since GHC 7.10 was released in 2015. Before that, it brought the <>
operator into scope so that compare = flip (comparing year) <> comparing mfg
can use it. In GHC 7.10, that operator was added to the Prelude, so it's now always in scope even without importing it.
As for what <>
does there, you're using it at the type Vehicle -> Vehicle -> Ordering
. It comes from the Semigroup b => Semigroup (a -> b)
instance (twice) and the Semigroup Ordering
instance. The net effect is that after applying both Vehicles
to it, it will use the result of the left-hand side comparison on them (flip (comparing year)
), unless it's EQ
, in which case it will use the right-hand side comparison (comparing mfg
) on them instead. If you were to write out by hand exactly what it were doing, it would be this:
compare x y = case flip (comparing year) x y of
LT -> LT
EQ -> comparing mfg x y
GT -> GT