flawr
flawr

Reputation: 11628

Can you "partially" derive a Typeclass?

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!

Upvotes: 7

Views: 222

Answers (1)

Li-yao Xia
Li-yao Xia

Reputation: 33399

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

Upvotes: 13

Related Questions