Search code examples
haskellfunctoreither

How to disregard a standard module?


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?


Solution

  • 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.