Lets say I have the following:
data Greek = Alpha | Beta | Gamma | Phi deriving Show
I want to use the default showing of all items except Beta, which I want to say "two".
Can I do this?
Lets say I have the following:
data Greek = Alpha | Beta | Gamma | Phi deriving Show
I want to use the default showing of all items except Beta, which I want to say "two".
Can I do this?
As far as I know, you can't. The deriving mechanism doesn't support anyway to alter or extend the derived instances.
deriving Show
uses the standard instanciating mechanism (simply returning the definition). If you want any special things, you will have to instanciate it manually:
data Greek = Alpha | Beta | Gamma | Phi
instance Show Greek
where
show Alpha = "Alpha"
show Beta = "2"
show Gamma = "Gamma"
show Phi = "Phi"
Not that this is entirely satisfactory, but you could do:
data Greek = Alpha | Beta | Gamma | Phi
deriving (Show)
showGreek Beta = "2"
showGreek x = show x
And use showGreek instead of show. If you needed a real show instance (in my code I find that I need this less than beginners tend to think), you could do the rather cumbersome:
newtype Greek' = Greek' Greek
instance Show Greek' where
show (Greek' g) = showGreek g
If it were my code, I'd just stick with showGreek
.
A nice rule of thumb I use is that the Show and Read instances are Haskell-generated only. If show doesn't produce valid Haskell code, it shouldn't be in a Show instance.
Some of the other suggestions work great in your particular example, and I would suggest to use those.
But in a more general case you might want to use datatype-generic programming.
Using generic programming, you can write functions that work on multiple data types, i.e. functions that do the same for every data type. Examples of such functions are show
and ==
(this is the reason those can be derived in GHC).
This is an example using the regular library:
{-# LANGUAGE TemplateHaskell, EmptyDataDecls, TypeFamilies #-}
import Generics.Regular
import qualified Generics.Regular.Functions.Show as G
data Greek = Alpha | Beta | Gamma | Phi
-- These two lines are all that is needed to use
-- Regulars generic functions on the 'Greek' data type.
$(deriveAll ''Greek "PFGreek")
type instance PF Greek = PFGreek
-- Manual written instance for 'Show'
instance Show Greek where
show Beta = "Two"
show x = G.show x -- Use Regulars 'show' for the boring parts
To be honest, I don't really like the output from Regulars show
function (it throws in an extra set of parentheses). But this might be a good starting point for writing your own generic functions.