
Jason Dagit wrote:
I tried to create a type class for making instances of Show display a custom way. After using my class for a while I found that sometimes RealFloats would display as 'NaN' and this is unacceptable. So at this point I had something like:
class Show a => StringValue a where toString :: a -> String
instance Num a => StringValue a where toString = show
instance RealFloat a => StringValue a where toString x | isNaN x = "" -- as an example | otherwise = show x
The simplest solution: replace the constraint RealFloat with its members. That is, replace "instance RealFloat a => StringValue a" with instance StringValue Float where toString x | isNaN x = "" -- as an example | otherwise = show x and the same for Double. There are currently only two members of RealFloat, so code duplication should not be so terrible. Or if it is, then you can do
{-# OPTIONS -fglasgow-exts #-} {-# OPTIONS -fallow-undecidable-instances #-} {-# OPTIONS -fallow-overlapping-instances #-}
class Show a => StringValue a where toString :: a -> String toString = show
instance Num a => StringValue a -- works for all Num except the following
instance StringValue Float where toString = myrealfloatthing instance StringValue Double where toString = myrealfloatthing
myrealfloatthing x | isNaN x = "" -- as an example | otherwise = show x
t1 = toString (1::Int) t2 = toString (1::Double) t3 = toString ((0.0::Double)/0.0)
A more general solution will use generic programming. I doubt however it will be much shorter than the above.