从了解您的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
类型。歧义在哪里,这里?
答案 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