Reputation: 23759
I am playing with Monoids now and wanted to define my instances of <>
and mempty
for a list. I wrote this:
instance Semigroup [a] where
(<>) = (++)
instance Monoid [a] where
mempty = []
But got an error:
Duplicate instance declarations:
instance Monoid [a] -- Defined at newtype.hs:25:10
instance Monoid [a] -- Defined in ‘GHC.Base’
Probably, I need to add this at the beginning of file:
import Prelude hiding (???)
What should I write in place of "???"?
Upvotes: 3
Views: 677
Reputation: 477824
The Haskell report says:
Instance declarations cannot be explicitly named on import or export lists. All instances in scope within a module are always exported and any import brings all instances in from the imported module. Thus, an instance declaration is in scope if and only if a chain of import declarations leads to the module containing the instance declaration.
It is thus not possible to exclude a certain instance. That being said, here it is not necessary at all to implement your Semigroup
and Monoid
for a list, since it is already defined. Indeed if, we inspect the source code, we see for Semigroup
[src]:
-- | @since 4.9.0.0 instance Semigroup [a] where (<>) = (++) {-# INLINE (<>) #-} stimes = stimesList
and for Monoid
[src]:
-- | @since 2.01 instance Monoid [a] where {-# INLINE mempty #-} mempty = [] {-# INLINE mconcat #-} mconcat xss = [x | xs <- xss, x <- xs]
So this is already implemented exactly the way you implemented this yourself.
It is usually considered an anti-pattern to implement an instance of a typeclass you did not implement yourself, on a data type you did not implement yourself. This is called an orphan instance [haskell-wiki]:
An orphan instance is a type class instance for class C and type T which is neither defined in the module where C is defined nor in the module where T is defined.
Usually one wraps a type into another data constructor (with newtype
) to define different instances for that type for a typeclass.
Upvotes: 6