2022-09-06
Today I was reviewing the difference between types and typeclasses in Haskell.
data keywordThe data keyword makes a new type.
This could be like a struct, with multiple named fields:
data Card = Card { suit :: Suit,
value :: Value }
deriving (Eq, Show)
It could have one field:
data Thing a = This a | That a deriving Show
Or it might not have any fields (like an enum):
data Suit = Clubs | Diamonds | Hearts | Spades
deriving (Eq, Show)
data Value = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King
deriving (Eq, Ord, Show)
type keywordThe type keyword makes a type synonym: it let's you give an existing type a new name:
type Deck = [Card]
This is cheaper than making a new type, as the compiler doesn't have to make a new type - it just let's you call an old one by a new name.
class keywordThe class keyword makes a new typeclass. Typeclasses describe behaviour in Haskell.
Eq, Ord, Show are all type classes:
Members of Eq can be compared with the == function
Members of Ord can be compared with <,>,>=, etc
Members of show can be rendered (show converts to a string, which can then be printed)
In the examples above we can 'derive' Eq and Show because the compiler can check if the values are the same and convert them to a string. With the Value type we also derived Ord - the compiler orders them in the order they are declared.
Typeclasses are like interfaces in object oriented programming. They contain function declarations that must be implemented to conform to the interface.
To implement Ord we can just implement compare and the compiler can deduce the other functions needed. Here's an example:
data Play = Rock | Paper | Scissors
deriving (Show, Eq)
instance Ord Play where
compare Paper Rock = GT
compare Rock Scissors = GT
compare Scissors Paper = GT
compare _ _ = LT