Instances in libraries (e.g., Control.Monad)

Simon Marlow
Fri, 15 Nov 2002 15:48:37 -0000

> As noted elsewhere, we've been running into problems with Haskell's
> "fine" handling of instances while trying to combine some largish
> Haskell projects. As long as the language isn't changed, this
> problem needs to be accounted for in library designs.
> Concrete examples: Control.Monad.Error, Control.Monad.Reader

A meta point: as far as I'm concerned, the design of any library that is
marked "experimental" (see the top of the page for each module in the
Haddock docs) is up for grabs.  Come up with a proposal, and if there's
a concensus it goes in.

(all the Control.Monad.* libraries are marked experimental, BTW).

>   These modules define lots of instances for (Either a) and ((->) a).
>   Why?  Obviously, they want to use them, but that's no excuse.
>   Both Either and (->) are very popular type constructors, and
>   currently, every project that wants to use these instances defines
>   them somewhere.  Result: as soon as you put two of these projects
>   together, you get a clash!
> In current Haskell, defining instances of public classes for public
> types/constructors has side-effects running through the whole of any
> program using such a library. Quite apart from the facts that the
> module names typically gives no indication of these side-effects,
> and that the modules could have been implemented without them (using
> standard types/constructors was just more convenient), there's no
> way to get two such modules to work together in a larger project
> without changing them!

IMO, given the current design of Haskell 98, instances should be
considered to be global.  There is only room for one instance for each
type/class pair in any program (including the libraries).  Otherwise the
library documentation has to publish for each module, a list of all the
instances defined by it and all modules below it in the dependency tree.
I think this is just silly.

If the library defines a particular instance, then you can't redefine

(interesting bits snipped)

> ShowFunctions.hs would have been an example of this (where did
> that go, btw?).

Text.Show.Functions, of course ;-)

(more interesting bits snipped)

> PS. perhaps this suggestion got lost in the other thread, but=20
>     could Haddock please show the source of any instances in the
>     generated documentation?

Showing the source of each instance isn't enough.  You need to list each
module that exports it.  That includes every module which depends,
directly or indirectly, on the module that defines it.  I *really* don't
want to do this - every module in the Haddock docs is going to have a
huge list of irrelevant instances attached to it.  I could put them in a
separate page, but it's still a pain.

While correct, this is going to be quite unwieldy.  But there's no
getting away from the fact that you still need to know which module to
import in order to gain access to a particular instance. =20