You can accomplish this using Data and Typeable. Of course, this is a hack, and this example only works for the "enumerated" types, as in your example.
I am sure that we will be able to understand in more detail how we do it, but to cover your example:
{-# LANGUAGE DeriveDataTypeable #-} import Data.Data import Data.Typeable data Greek = Alpha | Beta | Gamma | Delta | Eta | Number Int deriving (Data,Typeable) instance Show Greek where show Number n = show n show x = show $ toConstr x
This approach, as I implemented it, cannot handle nested data structures or something even more distant, but again, it's an ugly hack. If you really should use this approach, you can delve into the Data.Data package, I'm sure you could put something together ...
Here is a blog post giving a brief introduction to the packages: http://chrisdone.com/posts/data-typeable
The correct way to do this is to use the newtype wrapper. I understand that this is not the most convenient solution, although, especially when using GHCi, but it does not incur additional overhead and it is less likely that an unexpected path will unexpectedly arise as your program grows.
data Greek = Alpha | Beta | Gamma | Delta | Eta | Number Int deriving (Show) newtype SpecialPrint = SpecialPrint Greek instance Show SpecialPrint where show (SpecialPrint (Number x)) = "Number: " ++ show x show (SpecialPrint x) = show x main = do print (SpecialPrint Alpha) print (SpecialPrint $ Number 1)
source share