"Subclasses" show in Haskell?

Say I have the following:

data Greek = Alpha | Beta | Gamma | Phi deriving Show 

I want to use the default readings for all elements except Beta, which I want to say "two."

Can I do it?

+6
types haskell typeclass
source share
4 answers

deriving Show uses a standard instance creation mechanism (simply returning a definition). If you need any special things, you will have to create them manually:

 data Greek = Alpha | Beta | Gamma | Phi instance Show Greek where show Alpha = "Alpha" show Beta = "2" show Gamma = "Gamma" show Phi = "Phi" 
+17
source share

Not that this is completely 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 need a real instance to display (in my code, I think I need it less than beginners think), you can do it rather cumbersome:

 newtype Greek' = Greek' Greek instance Show Greek' where show (Greek' g) = showGreek g 

If this were my code, I would just stick with showGreek .

The good rule of thumb that I use is that Show and Read instances are generated only by Haskell. If show does not generate valid Haskell code, it should not be in the Show instance.

+7
source share

Some of the other suggestions work fine in your specific example, and I would suggest using them.

But in a more general case, you can use datatype-generic programming .

Using universal programming, you can write functions that work with several types of data, i.e. functions that do the same for each data type. Examples of such functions are show and == (for this reason they can be obtained in the 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 

Honestly, I don’t really like the way out of the Regulars show function (it produces an extra set of parentheses). But this can be a good starting point for writing your own common functions.

+4
source share

As far as I know, you cannot. The output mechanism does not support in any way modifying or extending derived instances.

+3
source share

All Articles