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

Claus Reinke claus.reinke at talk21.com
Wed Jun 30 03:36:00 EDT 2010

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

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

Note that my opposition is against making 'Monad (Either a)' less
defined and less tunable than it is at the moment. One could also
wonder whether the instance should be in Data.Either (the instance
for Maybe is in Data.Maybe), whether mtl should simply be changed
to use something other than Either, so that mtl's Either-variant and
its MonadError instances could remain together, or what the effect
of removing Error and moving the 'Monad (Either a)' instance would
be on the remainder of mtl's code.

To those '+1' fans: please compare what the proposal actually
does to what you would like to see. Most of us have had bad
experiences with these instances or with Haskell's instance
import behaviour (my own complaints go back to 2003 or so).
So most of us are happy to see something move. But fixing
a less defined 'Monad (Either a)' instance even higher in the
package hierarchy is not going to help. Do Ross and us all
a favour and study his proposal and the consequences
before voting.

|A reasonable case can be made for the existence of a monad that does
|something useful with fail.

Every Monad should try to do its best with fail. If, at some point,
fail in Monad gets replaced with throwError in MonadError, or
with mzero in MonadZero, or with something else, we can ignore
fail in Monad, but I would still expect pattern match error via fail
to integrate well with at least one of MonadPlus or MonadError.

|I don't think that that monad should be Either.
|'Either' takes on the connotation of being the 'sum type' for the category
|of Haskell types. This sum type has a very well formed and simple monad,
|that has a lot of useful theoretical properties, and is useful in a 
|larger array of scenarios than the monad with the error constraint, with
|the one notable exception that it doesn't handle the 'fail' property that
|was bolted into Monad in Haskell 98.

Remember that we are talking about Haskell, not category theory. If
you want to define a duplicate of Either with additional properties,
go ahead. But don't forget to duplicate the existing Either libraries.
If Haskell had parameterized modules, we could pass our choice
of Either-alternative to both mtl's modules and Either libraries, and
everone could be happy. As long as we don't have that option, I
don't see why Haskell's sum type cannot have a useful fail.

If you are just concerned about the Error constraint, simply provide
a default instance that maps strMsg to error (see example of default
instances with user override in base Data.Typable). That way, you'd
get 'Monad (Either a)' without Error constraint, but with strictly more
defined fail ('Left _|_' instead of '_|_'), and others can add even more
defined fail when needed.

If you are concerned about something else, please explain how a
less defined instance in Control.Monad.Instances is going to
address your concern in a way a more defined instance cannot.


More information about the Libraries mailing list