#4159: move Monad and MonadFix instances for Either from mtl to base

Claus Reinke claus.reinke at talk21.com
Tue Jun 29 15:16:03 EDT 2010

"Ross Paterson" <ross at soi.city.ac.uk> schrieb im Newsbeitrag 
news:20100629092649.GA3460 at soi.city.ac.uk...
> The proposal is to move the Monad and MonadFix instances for Either
> (currently in the mtl package) to Control.Monad.Instances and
> Control.Monad.Fix respectively (both in the base package).  The Monad
> instance is still an orphan, to retain Haskell 98 compatibility, but the
> MonadFix instance is together with its class.  The Error constraint is
> removed from both instances, and the default definition of fail is used.
> Discussion deadline: 20th July 2010

-1, because the default definition of fail is error, which would
render the Monad instance useless (unless I'm missing something?).

This has never been the Monad instance I wanted for Either
(I only use Either if I care about both alternatives, and fail=error
would spoil that), nor do I think that there is a single generally
useful instance that would improve the existing one in mtl:

0 defining 'instance Fail a => Monad (Either a)' would prevent
    any instances; but sometimes, Monad (Either String) is useful,
    so this is no good

1 leaving out the instance would let me define my own; but
    so could everyone else, so conflicts loom - again, no good

2a I don't like the Error constraint, but I can live with it (almost,
    because even two libs defining the same instance result
    in conflict); doesn't work in the long term
2b just moving the existing instance unchanged from
    Control.Monad.Error into Control.Monad.Instances
    might be an acceptable improvement

3a limiting the Monad instance to (Either String) with fail as
    Left would cover the only variant of Monad (Either a) that
    I've actually used myself; this is no good if there are actually
    any other Monad (Either a) instances in use
3b even 'fail s = Left (error s)' would be preferable to
    'fail = error', if you insist on dropping Error; but no good,
    that would take away programmer choice (and prevent
    my only use case!)

4 using 'fail = error' is the worst of all choices, and certainly
    shouldn't be moved in a position where I cannot avoid
    it (the other instances in Control.Monad.Instances are
    occasionally useful, this one wouldn't be); this is also
    inconsistent with the existing Monad Maybe instance,
    and doesn't tie in with MonadPlus (Either e): whenever
    possible, fail s should be mzero; this is no good at all.

Of these, only 2b seems acceptable, helping to prevent
conflicting equivalent instances for the only use case I've
encountered, Monad (Either String). 3b can be recovered
from 2b (noMsg defaults to strMsg "", strMsg defaults to
const noMsg; one could change the default of strMsg to
error, to preserve the error message).

In other words, the current design is annoying, but not
nearly as bad as the alternatives - the only improvements
would be to move the instances out of mtl, to avoid
conflicts, and perhaps to change the default of strMsg.



More information about the Libraries mailing list