broken Monad Either instance?

Ben Millwood haskell at benmachine.co.uk
Mon Nov 28 15:30:54 CET 2011


On Mon, Nov 28, 2011 at 1:17 PM, Christian Maeder
<Christian.Maeder at dfki.de> wrote:
> Hi,
>
> I was surprised to see my code break with ghc-7, due to changed monad
> instances:
>
> With ghc-6.12.3 I have:
>
> Prelude> :m Control.Monad.Error
> Prelude Control.Monad.Error>  fail "Bla" :: Either String ()
> Loading package mtl-1.1.0.2 ... linking ... done.
> Left "Bla"
>
> but with ghc-7.0.4 and ghc-7.2.2 I get a fatal exception:
>
> *Main> fail "Bla" :: Either String ()
> *** Exception: Bla
>
> I always viewed "Either String" as an alternative to Maybe with a failure
> message.
>
> The instance in ghc-7 comes from Control.Monad.Instances:
>  instance Monad (Either e) where
>        return = Right
>        Left  l >>= _ = Left l
>        Right r >>= k = k r
>
> which indeed uses "error" as default implementation of fail. Is there
> (supposed to be) an overlapping "instance Monad (Either String)" somewhere
> else?
>
> Any comments (or notes) that I missed?
>
> Cheers Christian
>

It's not exactly a bug, it's a change in behaviour. Beforehand, there
was no overlapping instance, the instance was just
'instance (Error e) => Monad (Either e) where' but the Error
constraint proved to be more a hindrance than a help, since it
prevented the instance being used with Left things that weren't
Errors, even though that's often a useful thing to do. So it was
agreed that the Error constraint should be removed, breaking 'fail'
but making the instance much more generally applicable.

Overlapping instances could be added for individual types, but
overlapping instances are usually considered to cause more problems
than they solve – ambiguity can easily arise in polymorphic functions
over Either.

Either still works as Maybe with added information, except now you
lose the do-pattern-matching magic. Sometimes I use something like
this:

> maybe (Left "oh no!") Right $ do
>   x:xs <- Just blah
>   [...]

to use little bits of Maybe inside an Either do. Notice I get control
of the error message here, too, so I can usually make it more useful.



More information about the Libraries mailing list