Haskell Deriving in Depth
Deriving in depth is how GHC fills in typeclass instances from a type definition. It turns one short deriving list into working Show, Eq, and Ord behaviour.
Constructor order decides derived Ord
Mon comes before Tue in the definition. The comparison follows that order.
data Day = Mon | Tue | Wed deriving (Show, Eq, Ord)
main :: IO ()
main = print (Mon < Tue, Tue < Wed, Wed < Mon)A newtype can derive Ord too
Score wraps one Int. The derived Ord compares the wrapped numbers.
newtype Score = Score Int deriving (Show, Eq, Ord)
main :: IO ()
main = print (Score 9 > Score 4, Score 4 == Score 4)Derived Eq and Show work together
Red and Green are different constructors. Equality says so, and Show prints the constructor name.
data Color = Red | Green deriving (Show, Eq)
main :: IO ()
main = do
print (Red == Green)
print RedExample
data Level = Bronze | Silver | Gold deriving (Show, Eq, Ord)
newtype Points = Points Int deriving (Show, Eq, Ord)
main :: IO ()
main = do
print (Bronze < Silver)
print (Gold < Bronze)
print (Points 80 > Points 60)Key points
- Deriving: GHC writes the instance code for the listed classes.
- Constructor order: the order of constructors decides derived Ord.
- Derived Eq: two values are equal only when they use the same constructor and the same fields.
- Derived Show: GHC prints a value in the same shape as its constructor.
- Newtype deriving: a newtype can derive the same classes as a data type.
In this example, Level derives Show, Eq, and Ord, and Points is a newtype with the same deriving list. The first print checks constructor order, the second checks the reverse order, and the third checks the wrapped Int values.
Note
derived Ord compares constructors before it compares fields.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Haskell Playground
Exercise
What decides the result of derived Ord for a custom type?