我有一个类似于previous one的问题,但超类是Eq
。例如,假设我有以下内容:
{-# LANGUAGE DefaultSignatures #-}
class (Eq a) => Foo a where
size :: a -> Int
(==) :: a -> a -> Bool
(==) s t = (size s) == (size t)
(注意,我已经包含了上述问题解决方案中建议的语言扩展名)
我收到以下ghci错误消息:
Ambiguous occurrence ‘==’ It could refer to either ‘Main.==’, defined at permutations.lhs:162:3 or ‘Prelude.==’, imported from ‘Prelude’ at permutations.lhs:1:1 (and originally defined in ‘GHC.Classes’)
我是否想在Haskell做一些不可能的事情?我知道我可以做一些像
这样的事情class (Eq a) => Foo a where
size :: a -> Int
data Bar = Qux [Int]
instance Foo Bar where
size (Qux xs) = length xs
instance Eq Bar where
(==) f g = (size f) == (size g)
但我必须为(==)
的每个实例复制Foo
的定义,而不是将其作为默认定义。
我也意识到,如果我使用自己的超类代替Eq
,我本来可以写的
class Bam a where
eqs :: a -> a -> Bool
default eqs :: Roo a => a -> a -> Bool
eqs f g = (size f) == (size g)
class (Bam a) => Roo a where
size :: a -> Int
我遇到的问题是超类是Eq
,而且我不想在每个实例中重复相同的定义。
答案 0 :(得分:1)
您可以定义具有相同名称的函数(和运算符),只要它们位于不同的模块中即可。
所以有Prelude.==
(默认值为1)和你的(例如My.==
)。在My.==
的默认定义中,
编译器不知道使用哪个。修复是微不足道的,但很难看:
{-# LANGUAGE DefaultSignatures #-}
module My where
class (Eq a) => Foo a where
size :: a -> Int
(==) :: a -> a -> Bool
(==) s t = (size s) Prelude.== (size t)
instance Eq a => Foo [a] where
size = length
main :: IO ()
main = do
print $ a Prelude.== b
print $ a My.== b
where
a = [1, 2, 3]
b = [3, 4, 5]
运行时:
> main
False
True
然而,我更喜欢使用其他一些运营商名称,例如~=
。