sortinghaskellcomparesemigroup

What does Data.Semigroup ((<>)) do in this Haskell sort code?


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 

Solution

  • 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