Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguous occurrence '=='

I'm just learning Haskell and still trying to figure out how things work.

So I'm creating a list class that can hold a mixture of Int and Char.

data Algebra = Empty
|   Nmbr Int Algebra
|   Smbl Char Algebra

Then I try to make it an instance of Eq

instance Eq Algebra where
Empty == Empty              = True
(Nmbr x xl) == (Nmbr y yl)  = (x == y) && (xl==yl)
(Smbl x xl) == (Smbl y yl)  = (x == y) && (xl==yl)
_ == _                  = False

and I get an Ambiguous occurrence == compile error. It can't tell the difference between Main.== and Prelude.==. If I manually replace all == with Main.== or Prelude.== then it compiles fine.

I don't see why the compiler is having so much difficulty here. x and y are clearly defined as being Int or Char in each case. I've compared what I am doing to the numerous tutorial examples (eg http://www.haskell.org/tutorial/classes.html) and I can't determine why the compiler is being such a jerk in this situation :P

like image 603
Stephen Douglas Allen Avatar asked Jun 23 '14 01:06

Stephen Douglas Allen


1 Answers

You need to indent the body of your instance definition:

instance Eq Algebra where
  Empty == Empty              = True
  (Nmbr x xl) == (Nmbr y yl)  = (x == y) && (xl==yl)
  (Smbl x xl) == (Smbl y yl)  = (x == y) && (xl==yl)
  _ == _                  = False

Otherwise the compiler sees it as two things:

  • An instance Eq Algebra with an empty body, producing the default definitions of a == b = not (a /= b) and vice versa.

  • A definition of a new infix operator named ==.

Then using == in your code now produces an ambiguity between the == from Eq (defined in Prelude) and the == in your code (Main).

And yes, deriving Eq gives you exactly this kind of structural equality.

like image 158
Jon Purdy Avatar answered Oct 04 '22 09:10

Jon Purdy