in Main.hs
class A aable where
getName :: aable → String
clas开发者_开发知识库s B bable where
getName :: bable → String
returns this compilation error with Leksah/ghc
src\Main.hs:23:4:
Multiple declarations of `Main.getName'
Declared at: src\Main.hs:20:4
src\Main.hs:23:4
I need both to be able to return a name, with a different signification in both cases. Should I declare class A and B in two different modules ?
Kneejerk reaction: Use Show
. Reading better, I see that what you want is propably different semantically (despite identical type signatures). Why not use a different name? descriptionA
and descriptionB
perhaps? Declaring them in different modules would solve the compilation error, but (1) you still have two different things with the same name and (2) whenever you import both modules (unqualified), you'll get the same error.
When you have different data types that behave differently, but somewhat the same (as in, have the same methods but differing implementations), then it's Haskell classes to the rescue!
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"
(If you haven't seen record syntax yet, there's a good explanation at LYAH)
You can even be more general than that.
{-# 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\"}"
The OverlappingInstances language pragma is only necessary in this example if you keep both the Instance (Show a) => Named a
and the instance Named A
, since I made A
an instance of Show
by deriving it. Use language pragmas with caution and wisdom.
I made A
and B
data for illustrative purposes, but the (Show a)
instance illustrates how this could also be done just as easily for classes.
精彩评论