The following is a polymorphic data type in Haskell, interpreted by Hugs. I am trying to create an instance of Show for Equality.
The instance declaration says that if a type "a" is in Show, then Equality a is in Show. It should print the two arguments to the constructor Equals a b in the form "a = b".
data Equality a = Equals a a
instance (Show a) => Show (Equality a) where
show (Equals a b) = a ++ " = " ++ b
Yet, typing something into Hugs like "(Equality 9 9)" yields:
ERROR - C stack overflow
So, I tried indenting the "show (Equals a b)..." line with a couple of spaces. I'm not sure what the difference would be, but was just playing around and then got this:
Inferred type is not general enough
*** Expression : show
*** Expected type : Show (Equality a) => Equality a -> String
*** Inferred type : Show (Equality [Char]) => Equality [Char] -> String
Can anyone explain why these errors are occurring, or suggest a better way of implementing this show instance?
Thank you!
The indenting does matter due to Haskell's at-times-strange whitespace sensitivity. Without the indent, the compiler cannot tell that the following statement belongs to the where
.
The error that you are getting is because the polymorphic type, having no constraints, does not ensure that a
and b
can concatenated with the " = " string. What if you have Equals 1 1
. How would you concatenate that without making the Ints strings first?
However, if you show
a and b first, all works out because show
martials the values into something that can be concatenated with a String.
data Equality a = Equals a a
instance (Show a) => Show (Equality a) where
show (Equals a b) = (show a) ++ " = " ++ (show b)
Your code is indented incorrectly. It defines an empty Show
instance:
instance (Show a) => Show (Equality a) where
and a separate top-level function show
:
show (Equals a b) = a ++ " = " ++ b
of type Equality [Char] -> [Char]
. So when you try to use your Show
instance, the default definition of show
from the Show
class gets picked up. Looking at the code:
showsPrec _ x s = show x ++ s
show x = showsPrec zeroInt x ""
you can see that the default show
is defined in terms of showsPrec
, which is in turn defined in terms of show
. This explains why your program goes into an infinite loop.
To fix the code, indent it appropriately, and add missing calls to show
to fix the type error (which stems from the fact that you can't concatenate an arbitrary type a
with a string - you have to convert a
to a string first):
data Equality a = Equals a a
instance (Show a) => Show (Equality a) where
show (Equals a b) = show a ++ " = " ++ show b
Testing:
*Main> show (Equals 9 9)
"9 = 9"
I think your problem is that you didn't call function show
on arguments a
and b
. I did this in GHC but I think it should work:
data Equality a = Equals a a
instance (Show a) => Show (Equality a) where
show (Equals a b) = show a ++ " = " ++ show b
Then:
> Equals 9 9
9 = 9