在将类型创建为Eq的实例时,==的模糊出现

时间:2014-12-25 14:51:02

标签: haskell operator-overloading

了解您的Haskell以获得更好的

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

当我将其加载到ghci时,我收到错误:

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

据我了解,==此处特定于Trafficlight类型。歧义在哪里,这里?

1 个答案:

答案 0 :(得分:10)

问题实际上在class Eq1,而不在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 (==) ?

此时,您不清楚是否要使用Prelude.==Main.==。你需要说清楚:

class Eq1 a where
    (==) :: a -> a -> Bool
    (/=) :: a -> a -> Bool
    x == y = not (x Main./= y)
    x /= y = not (x Main.== y)

现在instance Eq1 Trafficlight将起作用,因为您确实定义了(==)实例的(/=)Eq1。不过请注意,Red == Yellow仍然不明确,因为手边有两个(==)(/=)。要解决此问题,您需要将所有来电的前缀加到==/=

最好为您的运营商使用其他名称:

class Eq1 a where
   (===), (=/=) :: a -> a -> Bool
   x === y = not $ x =/= y
   x =/= y = not $ x === y