Suppose I'd want to create a new data type and make the constructors showable, only in lower case instead of their upper case definition. For example:
data Day = Monday | Tuesday | Wednesday| Thursday | Friday | Saturday | Sunday
By adding deriving Show, ghci would print them as "Monday, Tuesday.. etc." To get it to show "monday, tuesday.. etc" I've tried to make a special instance of show:
import Data.Char
strToLower :: [Char] -> [Char]
strToLower (x:xs) = toLower x : strToLower xs
strToLower [] = []
instance Show Day where
show d = strToLower (show d)
where the first occurrence of show should designate my new amended show function (which will be called everytime I print) whereas for the second I intend the normally derived version of show, to get from the constructor name to a String.
Of course this doesn't work (circular definition) as the ghci has no clue to my separate meanings of the word "show" but I can't figure out how to let him know the distinction, for both versions need to be named show, the first because that's what print calls to and the second because it's a predefined haskell function which can give me a String out of a constructor name. I've tried
show d = strToLower ((showsPrec 0 d) "")
but this comes down to the same circular definition, at least that's what I guess from the ghci getting stuck in a loop.
I understand why constructor names need to begin with an upper case letter, but showing them lower case shouldn't be a problem, should it? I know I could just define my show function for every case separately, e.g. show Monday = "monday"
show Tuesday = "tuesday"
etc, but I'm only using the days of the week as an example here and my real data type consists of 64 constructors so I think it would be more elegant to solve it differently somehow.
Is it possible to dig into the haskell definition of show and alter a copy of that code? This is the only possible solution I can think of but I don't know how to do it, if it is possible at all. Probably not. So other solutions are very welcome as well!
Thank you for taking your time,
Jelle (Haskell beginner)
You can actually do this using the Typeable
and Data
classes.
To do this you need the DeriveDataTypeable
extension, turn it on with -XDeriveDataTypeable
or by putting the following line at the start of the file that defines your type:
{-# LANGUAGE DeriveDataTypeable #-}
You can now import the needed modules:
import Data.Data
import Data.Typeable
And derive Typeable
and Data
:
data Day = Monday | Tuesday | Wednesday| Thursday | Friday | Saturday | Sunday
deriving (Typeable, Data)
Now you can use toConstr
to get a constructor representation:
instance Show Day where
show = strToLower . showConstr . toConstr
But see the other answers on whether you'd really want to, instead of simply using a showDay
function or your own type class instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With