🎓 A1Learner
🔍
0 of 47 lessons completed

Haskell Generic Deriving

Generic deriving is asking the compiler to write a Generic instance for a type. One word in the deriving clause adds the whole representation.

One word adds the representation

Generic joins Show and Eq in the deriving clause. The round trip then prints True.

{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics (Generic, from, to)
data Box a = Box a deriving (Show, Eq, Generic)
main :: IO ()
main = print (to (from (Box 5)) == Box 5)

Records derive Generic the same way

A record type derives Generic in the same clause. Its round trip prints True too.

{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics (Generic, from, to)
data Person = Person String Int deriving (Show, Eq, Generic)
main :: IO ()
main = print (to (from (Person "Ana" 31)) == Person "Ana" 31)

A score type derives Generic the same way

A fresh type needs no hand-written instance. Deriving alone gives it the representation.

{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics (Generic, from, to)
data Score = Score String Int deriving (Show, Eq, Generic)
main :: IO ()
main = print (to (from (Score "Ana" 90)) == Score "Ana" 90)

Example

{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics (Generic, from, to)
data Box a = Box a deriving (Show, Eq, Generic)
data Person = Person String Int deriving (Show, Eq, Generic)
main :: IO ()
main = do print (to (from (Box 5)) == Box 5); print (to (from (Person "Ana" 31)) == Person "Ana" 31)

Key points

  • Deriving: asking the compiler to write an instance for a type.
  • DeriveGeneric: the language extension that allows deriving Generic.
  • Generic instance: the compiler-written link between a type and its representation.
  • Alongside: Generic sits in the same deriving clause as Show and Eq.
  • New type: any new type gains the representation as soon as it derives Generic.

In this example, Box and Person each derive Generic in their own clause, from turns each value into its representation, and to rebuilds each one so both checks print True.

Note

deriving Generic adds no runtime behaviour on its own, only the representation.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Haskell Playground

Exercise

Which pragma allows deriving Generic?