Ambiguous occurrence of == when creating a type as an instance of Eq
From Learn You Haskell for Great Good:
class Eq1 a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not (x /= y)
x /= y = not (x == y)
data TrafficLight = Red | Yellow | Green
instance Eq1 TrafficLight where
Red == Red = True
Green == Green = True
Yellow == Yellow = True
_ == _ = False
When I load this into ghci
I got the error:
baby.hs:213:9:
Ambiguous occurrence ‘==’
It could refer to either ‘Main.==’, defined at baby.hs:225:5
or ‘Prelude.==’,
imported from ‘Prelude’ at baby.hs:1:1
(and originally defined in ‘GHC.Classes’)
As far as I understand, ==
here is type specific Trafficlight
. Where is the ambiguity here?
source to share
The problem is actually in class Eq1
, not in instance Eq1 Trafficlight
:
class Eq1 a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not (x /= y) -- which (/=) ?
x /= y = not (x == y) -- which (==) ?
At this point, it is not clear if you want to use Prelude.==
or Main.==
. You should make it clear:
class Eq1 a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not (x Main./= y)
x /= y = not (x Main.== y)
Now instance Eq1 Trafficlight
to work, because you really define (==)
and (/=)
his copy Eq1
. However, keep in mind that it Red == Yellow
will still be ambiguous since there are actually two (==)
ands (/=)
. To fix this, you need to prefix all calls with ==
and /=
.
Better to use different names for your operators:
class Eq1 a where
(===), (=/=) :: a -> a -> Bool
x === y = not $ x =/= y
x =/= y = not $ x === y
source to share