As an exercise, I am trying to implement my own version of a standard Functor, in this case Either
.
My code looks similar to the standard definition:
instance Functor (Either a) where
fmap _ (Left x) = Left x
fmap f (Right y) = Right (f y)
When I attempt to compile it I get the following error:
ghc --make either.lhs
[1 of 1] Compiling Main ( either.lhs, either.o )
either.lhs:14:12: error:
Duplicate instance declarations:
instance Functor (Either a) -- Defined at either.lhs:14:12
instance Functor (Either a) -- Defined in ‘Data.Either’
make: *** [hs] Error 1
The compiler sees a conflict with the standard instance defined in Data.Either. This is despite that I do not actually import the Data.Either module in my code. I would like to compile and test my own Functor implementation -- is there some way that I can perhaps hide Data.Either from the compiler to avoid the conflict?
You have two options:
Either
.module Foo where
import Prelude hiding (Either)
data Either a b = Left a | Right b
instance Functor (Either a) where ...
Functor
.module Bar where
import Prelude hiding (Functor)
class Functor f where
fmap :: (a -> b) -> f a -> f b
instance Functor (Either a) where ...
As you discovered, you can also just make up non-clashing names rather than hiding things from the Prelude
. But learning to hide things is pretty important; for example, you'll see many programs doing this:
import Control.Category
import Prelude hiding (id, (.))
That's because those programs want to use the more general id
and (.)
from Control.Category
instead of the ones from the prelude.