[Haskell-cafe] Why Either = Left | Right instead of something like Result = Success | Failure

Daniel Fischer daniel.is.fischer at web.de
Fri May 28 20:13:59 EDT 2010


On Saturday 29 May 2010 01:28:59, Ivan Lazar Miljenovic wrote:
> Daniel Fischer <daniel.is.fischer at web.de> writes:
> > On Friday 28 May 2010 20:44:20, Donn Cave wrote:
> >> Quoth Vo Minh Thu <noteed at gmail.com>,
> >> ...
> >>
> >> > Control.Monad.Error provides an instance for Either.
> >>
> >> ... in the mtl transformer library, in case anyone else besides
> >> myself didn't know that. And I see it has to be there because
> >> it depends on the Error typeclass.
> >
> > Which is considered a wart by some. (Either left) has a perfectly
> > valid Monad instance for any type left (the only slightly difficult
> > thing might be 'fail').
>
> Though how would you set the Left value for some arbitrary type?
>

That is the difficult thing. If you want to have

instance Monad (Either e) where ...

, there are only two possibilities for fail that I see,

    fail msg = error msg
    -- or error somethingElse

    fail msg = Left undefined
    -- or Left (error msg)

Neither is entirely convincing, but the second is a little more robust 
(though you can't inspect failures without catching exceptions).
Constructing more meaningful Left values is then a little dangerous (if you 
try to inspect them) or pointless (if not).

But if you want to have

instance Monad (Either ConcreteType) where ...

, you can have

    fail msg = Left someDefaultValue

(or let the value depend on the message) and you can construct
Left someMeaningfulValue in concrete situations.

Of course, you can then also write

instance Error ConcreteType where
    noMsg = someDefaultValue
    strMsg msg = whatever

which really is no more fuss, so the 'bad' thing about it is just that if 
you want a Monad instance for (Either ConcreteType), you have to
- import Control.Monad.Error(.Class) and make ConcreteType an instance of 
Error, or
- make sure it's never used in the same module as C.M.E, or
- enable OverlappingInstances when they're used together.

Need I explain why I prefer the first?

> >> Though I can't really be sure what the documentation is
> >> trying to say.)
> >
> > In that case, have a look at the code, perhaps that is clearer. (And
> > bug the maintainer(s) to improve the docs.)
>
> IIRC, the basic point is that the Left type has to be one which can be
> converted from some arbitrary String value, to take into account the
> fail method for that type:
>
> fail :: (Monad m) => String -> m a

Yep.



More information about the Haskell-Cafe mailing list