Search code examples
haskellstack-overflowpolymorphismhugs

Why does this Show instance in Haskell (Hugs) cause a stack overflow error?


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!


Solution

  • 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)