dreaded non-modular instances; ghci bug, Either, and haddock

Claus Reinke claus.reinke@talk21.com
Fri, 25 Oct 2002 15:42:11 +0100


instances are the pride and joy of Haskell's module system..

1) instance documentation

Once introduced, instances propagate more or less everywhere, but I'm having
trouble identifying the source modules for surprising instances with ghc, where
I don't have the sources of the libraries, only .hi files and haddock-generated
documentation..

Here's an example error message from trying to link together two pieces of
Haskell
software, both working fine on their own (using ghc-5.04 on cygwin):

Duplicate instance declarations:
  ../tools/base/lib/Monads/ExceptM.hs:26: Functor (Either x)
  <No locn>: Functor (Either e)

Duplicate instance declarations:
  ../tools/base/lib/Monads/ExceptM.hs:29: Monad (Either x)
  <No locn>: Monad (Either e)

Now, how am I supposed to find out where those other instances come from?

Obviously, the error message could be better, but let's just assume I'd be
interested
in the question independent of any error messages: where do instances come from?

The way haddock groups that information in the ghc docs is not very helpful in
this case: looking at the Prelude doc, I see that, yes, Either is an instance of
Functor
and Monad (huh, in the Haskell Prelude? I don't think so..), but not where those
unexpected instances are defined..

Fortunately, ghc-5.02.3 on sunos is more informative in its error message (is
that
a sunos/windows difference, or did the info get lost between ghc-5.02.3 and
ghc-5.04?)
and suggests that the other instance might come from MonadError (btw, why?).
Even armed with that suggestion, I don't know an easy way to verify this,
though:
the docs don't mention a Functor instance for Either in Control.Monad.Error,
they
do in Control.Monad..

The .hi files don't seem to give me a hint, either..

Am I missing a trick? Or is the documentation of instances incomplete?


2) ghci instance handling

One way (the good old primitive way) is to test. ghci seems to confirm
that the Functor instance comes from MonadError, not from Monad, not
from Prelude, but..

ghci doesn't seem to clean up instances when switching between modules?

$ ghci -package lang
   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 5.04, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base ... linking ... done.
Loading package haskell98 ... linking ... done.
Loading package lang ... linking ... done.
Prelude>
Prelude> fmap not (Right True::Either Bool Bool)

<interactive>:1:
    No instance for (Functor (Either Bool))
    arising from use of `fmap' at <interactive>:1
    In the definition of `it':
        fmap not (Right True :: Either Bool Bool)

Prelude> :m Control.Monad
Prelude Control.Monad>  fmap not (Right True::Either Bool Bool)

<interactive>:1:
    No instance for (Functor (Either Bool))
    arising from use of `fmap' at <interactive>:1
    In the definition of `it':
        fmap not (Right True :: Either Bool Bool)

Prelude> :m MonadError
Prelude MonadError>  fmap not (Right True::Either Bool Bool)
Right False
Prelude MonadError> :m Prelude
Prelude>  fmap not (Right True::Either Bool Bool)
Right False
Prelude> fmap not (Left True::Either Bool Bool)
Left True
Prelude>

Cheers,
Claus

PS. user's guide, ghci section, has %lt; instead of &lt; (<)