qed*_*qed 3 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
Run Code Online (Sandbox Code Playgroud)
当我加载它时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’)
Run Code Online (Sandbox Code Playgroud)
据我了解,==这里有具体的Trafficlight类型.歧义在哪里,这里?
Zet*_*eta 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 (==) ?
Run Code Online (Sandbox Code Playgroud)
那时候还不清楚你是否想要使用Prelude.==或Main.==.你需要说清楚:
class Eq1 a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not (x Main./= y)
x /= y = not (x Main.== y)
Run Code Online (Sandbox Code Playgroud)
现在instance Eq1 Trafficlight将工作,因为你真的定义(==)和(/=)您的Eq1实例.但是,请记住,Red == Yellow这仍然是模棱两可的,因为实际上有两个(==)并且(/=)在手边.为了解决这个问题,您需要将所有调用前缀添加到==和/=.
更好地为您的运营商使用其他名称:
class Eq1 a where
(===), (=/=) :: a -> a -> Bool
x === y = not $ x =/= y
x =/= y = not $ x === y
Run Code Online (Sandbox Code Playgroud)