Haskell 将类型创建为Eq的实例时,出现不明确的==
从中学习Haskell for Great Good: 当我将其加载到Haskell 将类型创建为Eq的实例时,出现不明确的==,haskell,operator-overloading,Haskell,Operator Overloading,从中学习Haskell for Great Good: 当我将其加载到ghci中时,我得到一个错误: baby.hs:213:9: Ambiguous occurrence ‘==’ It could refer to either ‘Main.==’, defined at baby.hs:225:5 or ‘Prelude.==’, imported from ‘Pr
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
类型的。这里的歧义在哪里?问题实际上在类Eq1
中,而不是实例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)
现在实例Eq1 Trafficlight
将起作用,因为您正在定义实例的(==)
和(/=)
。但是,请记住,红色==黄色
仍然是不明确的,因为实际上有两个(==)
和(/=)
。为了解决这个问题,您需要在所有调用=
和/=
之前加上前缀
最好为您的操作员使用其他名称:
class Eq1 a where
(===), (=/=) :: a -> a -> Bool
x === y = not $ x =/= y
x =/= y = not $ x === y
这是因为Eq1重新定义了==。如果您省略了所有Eq1声明,只使用Prelude(自动导入)中为您定义的Eq,它将正常工作。如果出于某种原因您想要自己的Eq1,请不要将其命名为==。您可以通过在文件顶部添加一个明确的导入声明来隐藏标准前奏曲中Eq
中定义的=
和/=
:导入前奏隐藏((==),(/=)
。操作符周围的额外()
将中缀操作符更改为普通符号。
class Eq1 a where
(===), (=/=) :: a -> a -> Bool
x === y = not $ x =/= y
x =/= y = not $ x === y