0

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?

mherzl
  • 5,624
  • 6
  • 34
  • 75
  • 3
    You can't access the `Either` type from that module, yet not have its related instances in scope. You should define your own `Either` type instead. – chi May 18 '17 at 21:44
  • Relevant: [*Explicitly import instances*](http://stackoverflow.com/q/8728596/2751851) – duplode May 18 '17 at 21:52
  • I got something to work by defining my own `Either'` type. – mherzl May 18 '17 at 21:54

1 Answers1

3

You have two options:

Define your own Either.

module Foo where
import Prelude hiding (Either)

data Either a b = Left a | Right b

instance Functor (Either a) where ...

Define your own 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.

dfeuer
  • 48,079
  • 5
  • 63
  • 167