On Saturday 29 May 2010 01:28:59, Ivan Lazar Miljenovic wrote:
> Daniel Fischer <daniel.is.fischer@xxxxxx> writes:
> > On Friday 28 May 2010 20:44:20, Donn Cave wrote:
> >> Quoth Vo Minh Thu <noteed@xxxxxxxxx>,
> >> ...
> >> > 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
- 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
Haskell-Cafe mailing list