class A aable where
getName :: aable → String
class B bable where
getName :: bable → String
使用Leksah / ghc
返回此编译错误src\Main.hs:23:4:
Multiple declarations of `Main.getName'
Declared at: src\Main.hs:20:4
src\Main.hs:23:4
我需要两者都能够返回一个名称,在两种情况下都有不同的含义。 我应该在两个不同的模块中声明A类和B类吗?
答案 0 :(得分:3)
Kneejerk反应:使用Show
。阅读更好,我看到你想要的是语义上不同的(尽管类型签名相同)。为什么不使用不同的名字?也许descriptionA
和descriptionB
?在不同的模块中声明它们可以解决编译错误,但是(1)你仍然有两个不同的东西具有相同的名称,(2)每当你导入两个模块(不合格)时,你都会得到同样的错误。
答案 1 :(得分:3)
如果你有不同的数据类型,但行为不同,但有些相同(如同,有相同的方法但不同的实现),那么它就是Haskell类来拯救!
data A = A { nameA :: String } deriving (Show, Eq)
data B = B { nameB :: String } deriving (Show, Eq)
class Named a where
getName :: a -> String
instance Named A where
getName = nameA
instance Named B where
getName = nameB
ghci> getName $ A "foo"
"foo"
ghci> getName $ B "bar"
"bar"
(如果你还没有看过记录语法,那就是good explanation at LYAH)
你甚至可以更加一般。
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}
-- The above line should be at the top of your file
-- add this to the file too (anywhere)
instance (Show a) => Named a where
getName = show
ghci> getName 3
"3"
ghci> show 3
"3"
ghci> getName $ A "foo"
"foo"
ghci> show $ A "foo"
"A {nameA = \"foo\"}"
如果同时保留Instance (Show a) => Named a
和instance Named A
,则只需在此示例中使用OverlappingInstances语言编译指示,因为我通过派生A
Show
实例A
。谨慎而谨慎地使用语言编译语。
我提供了B
和(Show a)
数据用于说明目的,但{{1}}实例说明了如何在类中轻松完成此操作。