Lance Pollard
Lance Pollard

Reputation: 79368

What happens under the hood with `deriving` in Haskell?

I am just beginning to learn Haskell. I have seen many intro examples explaining the basics of types, but they often have a deriving statement below the type. Here is an example from Chapter 3 of RealWorldHaskell:

data Cartesian2D = Cartesian2D Double Double
                   deriving (Eq, Show)

data Polar2D = Polar2D Double Double
               deriving (Eq, Show)

They explain deriving somewhat in Chapter 6, which helps you know how it is used.

So far from what I understand, deriving (Show) is necessary to tell Haskell how to turn your type into a string. That makes sense at a practical level. I come from JavaScript land, so to me you could easily imagine this would be implemented like:

Polar2D.prototype.toString = function(){
  return '[Polar2D]';
};

In Haskell, they give the example of how to implement your own Show for the Color type, instead of using deriving.

data Color = Red | Green | Blue
instance Show Color where
  Red = "red"
  Green = "green"
  Blue = "blue"

That means when your in the ghci repl, you can do:

> show Red
"red"

But this doesn't explain what deriving is actually doing, it's still magic to me.

My question is, what is happening under the hood with deriving? Also, is there a place on GitHub in the Haskell source where you can see the implementation? That may also be helpful.

Upvotes: 14

Views: 348

Answers (1)

Stephen Diehl
Stephen Diehl

Reputation: 8419

GHC is effectively just writing the same instance you wrote by hand, if you pass -ddump-deriv to the compiler you can see the code it generates. For instance:

Prelude> data Color = Red | Green | Blue deriving (Show)

==================== Derived instances ====================
Derived instances:
  instance Show Color where
    showsPrec _ Red = showString "Red"
    showsPrec _ Green = showString "Green"
    showsPrec _ Blue = showString "Blue"
    showList = showList__ (showsPrec 0)


Generic representation:

  Generated datatypes for meta-information:

  Representation types:

There's not really much magic going on here, Show just has a very mechanical implementation. Inside it looks at the internal form of the data constructors (the type is DataConRep in GHC's source ) which it gets from translating the frontend AST and then looks at the names provided in the frontend source and adds a new Show instance in terms of these names and any nested types that also implement Show. The new auto-generated typeclass is registered just like a hand-coded class as if it were written in the current module.

Upvotes: 16

Related Questions