RC 2022 Day 21 - Haskell types

2022-09-06

Today I was reviewing the difference between types and typeclasses in Haskell.

The data keyword

The 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)

The type keyword

The 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.

The class keyword

The class keyword makes a new typeclass. Typeclasses describe behaviour in Haskell.

Eq, Ord, Show are all type classes:

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