Can you "partially" derive a Typeclass?

Viewed 186

In the following toy example we create a new type D for which we want to implement the typeclass Show. Now let's say for all constructors the derived show function would be just fine, except for one special case A for which we want to override that default.

Is it possible to do that, or can you just have all or none of them derived?

data D = A | B | C
  deriving (Show)

-- goal: 
-- show A = "A is special"
-- show B = "B"
-- show C = "C"

main = print $ show A

Try it online!

1 Answers

This can be done using generics. generic-data provides a default implementation of showsPrec, gshowsPrec, and you can use pattern-matching to handle non-default cases before it:

{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics
import Generic.Data (gshowsPrec)

data D = A | B | C
  deriving (Generic)

instance Show D where
  showsPrec _ A = ("A is special" ++)
  showsPrec n x = gshowsPrec n x
Related