instance Monad (Either String) in Prelude or Data.Either?

Is there any particular reason to not move the instance to the prelude? A module was failing when imported from one place and ok when imported from another, so I spent a frustrating 10 minutes searching for the instance. I couldn't find a way to search haddock for instances (not even grep on the html), nor hoogle, nor anything else. Finally I turned to google and found a couple of haskell-cafe threads with people wondering why other people's code failed for them. This was especially frustrating because I knew I had written my own instance when I originally couldn't find it, then removed my own when I did find it, then forgot where I found it *two times* so I knew it existed, just not where. So this is the third time I've done this search. Now I have a few commented 'import Control.Monad.Error ()' scattered about in a few "low level" modules to try to make sure it's visible everywhere and next time I go hunting I can look in my own modules. If orphan instances are discouraged, shouldn't the instance for Monad Either be declared where Either is? This should probably go for Functor Either too. I notice that Monad Maybe is in Prelude, and it would be a pain if it weren't. If there's no particular reason to not move it, I'll do a libraries proposal... or since it involves the prelude should this be haskell-prime?

Unfortunately, the instance of Monad for Either a is somewhat misguided in
Haskell.
There is a spurious restraint that the Left value in your Either be a member
of some Error class, which was brought about by the deletion of MonadZero
from Haskell 98 (as part of the elimination of failure free patterns, and an
attempted simplification of the language).
In order to support the arguable misfeature of including 'fail' in Monad,
the Either instance for Monad has this extra constraint.
That in and of itself is only mildly annoying, but then to use that
constraint requires a multi-parameter type class for MonadError, which isn't
a Haskell 98 feature. So it isn't in the standard prelude, which tries to
limit itself to that which could be plausibly implemented as Haskell 98, but
instead sits off in one of the dozen or so monad transformer library
variants floating around.
In theory, this is good, because you can then define your own monad instance
for Either without that constraint -- if you don't care to exploit the Error
instance's ability to get fail to work. Or you want a real Either monad for
tricks like Oleg's recent post on the constructive law of excluded middle,
or to talk about apomorphisms as a generalized anamorphism, parameterized on
the either monad so it can be symmetrical to paramorphisms. In practice,
you link in someone's code that links in the MTL, and then you're stuck
using the MTL instance anyways.
-Edward Kmett
On Thu, Sep 10, 2009 at 9:03 PM, Evan Laforge
Is there any particular reason to not move the instance to the prelude? A module was failing when imported from one place and ok when imported from another, so I spent a frustrating 10 minutes searching for the instance. I couldn't find a way to search haddock for instances (not even grep on the html), nor hoogle, nor anything else. Finally I turned to google and found a couple of haskell-cafe threads with people wondering why other people's code failed for them. This was especially frustrating because I knew I had written my own instance when I originally couldn't find it, then removed my own when I did find it, then forgot where I found it *two times* so I knew it existed, just not where. So this is the third time I've done this search. Now I have a few commented 'import Control.Monad.Error ()' scattered about in a few "low level" modules to try to make sure it's visible everywhere and next time I go hunting I can look in my own modules.
If orphan instances are discouraged, shouldn't the instance for Monad Either be declared where Either is? This should probably go for Functor Either too. I notice that Monad Maybe is in Prelude, and it would be a pain if it weren't.
If there's no particular reason to not move it, I'll do a libraries proposal... or since it involves the prelude should this be haskell-prime? _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Fri, Sep 11, 2009 at 6:10 AM, Edward Kmett
Unfortunately, the instance of Monad for Either a is somewhat misguided in Haskell.
There is a spurious restraint that the Left value in your Either be a member of some Error class, which was brought about by the deletion of MonadZero from Haskell 98 (as part of the elimination of failure free patterns, and an attempted simplification of the language).
I just tried it, and my own instance for Monad (Either String) (all I'm really interested in anyway) can coexist with the one for Error e => Monad (Either e). But indeed, with the presence of fail, you can't write the general Monad (Either e) which "should" work. And it does require FlexibleInstances. I suppose as long as flexible instances aren't standard then even the String instance can't go in the Prelude.
In theory, this is good, because you can then define your own monad instance for Either without that constraint -- if you don't care to exploit the Error instance's ability to get fail to work. Or you want a real Either monad for tricks like Oleg's recent post on the constructive law of excluded middle, or to talk about apomorphisms as a generalized anamorphism, parameterized on the either monad so it can be symmetrical to paramorphisms. In practice, you link in someone's code that links in the MTL, and then you're stuck using the MTL instance anyways.
Right. I know there was some argument a while back, but I thought that position that instances are global period was pretty "official". At least it made sense to me. The more libraries you import the less control you have over the extent of what they may import. But I guess it wouldn't be haskell if every third person didn't have an idea for a better way to implement the mtl... I just want an exception with a message though!

Right. I know there was some argument a while back, but I thought that position that instances are global period was pretty "official". At least it made sense to me. The more libraries you import the less control you have over the extent of what they may import. But I guess it wouldn't be haskell if every third person didn't have an idea for a better way to implement the mtl... I just want an exception with a message though!
A few days ago I was trying to refactor some code to use transformers + monads-tf instead of mtl. Eventually I gave up after getting error messages about Either having conflicting Monad instances. A few of the libraries I'm using depend on mtl. if I understand you correctly, all libraries that software I write depends on, directly or indirectly, must be free of namespace conflicts. Is that correct?

if I understand you correctly, all libraries that software I write depends on, directly or indirectly, must be free of namespace conflicts. Is that correct?
Well, it may be more accurate to say that class instances have no namespaces, and are all implicitly global. When you import a module, you get all the instances it defines in the global namespace, whether you want them or not. Like I said, there was some argument with people on one side saying importing is a valid way of controlling instance visibility, and another side saying the fact that you have to import at all is an implementation artifact and instances should be considered global. Practically speaking, I buy the second argument more, for the reason you described above.

Evan Laforge schrieb:
On Fri, Sep 11, 2009 at 6:10 AM, Edward Kmett
wrote: Unfortunately, the instance of Monad for Either a is somewhat misguided in Haskell.
There is a spurious restraint that the Left value in your Either be a member of some Error class, which was brought about by the deletion of MonadZero from Haskell 98 (as part of the elimination of failure free patterns, and an attempted simplification of the language).
I just tried it, and my own instance for Monad (Either String) (all I'm really interested in anyway) can coexist with the one for Error e => Monad (Either e). But indeed, with the presence of fail, you can't write the general Monad (Either e) which "should" work. And it does require FlexibleInstances. I suppose as long as flexible instances aren't standard then even the String instance can't go in the Prelude.
Are you sure, that the instance cannot be defined in Haskell 98 using a helper type class for the Char datatype? http://www.haskell.org/haskellwiki/List_instance

You could, but then you need overlapping instances to define the one in Control.Monad.Error. -Edward Kmett On Sat, Sep 12, 2009 at 4:26 PM, Henning Thielemann < lemming@henning-thielemann.de> wrote:
Evan Laforge schrieb:
On Fri, Sep 11, 2009 at 6:10 AM, Edward Kmett
wrote: Unfortunately, the instance of Monad for Either a is somewhat misguided in Haskell.
There is a spurious restraint that the Left value in your Either be a member of some Error class, which was brought about by the deletion of MonadZero from Haskell 98 (as part of the elimination of failure free patterns, and an attempted simplification of the language).
I just tried it, and my own instance for Monad (Either String) (all I'm really interested in anyway) can coexist with the one for Error e => Monad (Either e). But indeed, with the presence of fail, you can't write the general Monad (Either e) which "should" work. And it does require FlexibleInstances. I suppose as long as flexible instances aren't standard then even the String instance can't go in the Prelude.
Are you sure, that the instance cannot be defined in Haskell 98 using a helper type class for the Char datatype? http://www.haskell.org/haskellwiki/List_instance
participants (4)
-
Edward Kmett
-
Evan Laforge
-
Henning Thielemann
-
Michael Steele