
I wrote:
An instance of Monad (Either a) is defined in Control.Monad.Error. Unfortunately, that instance requires the type "a" to be an instance of Error... The Either monad is more generally useful for any complex calculation that needs to exit in the middle and return a value, including multi-level exit... Could this restriction be removed?
Iavor Diatchki wrote:
...I tend to think of the error monad as an abstract type, and not assume that it is the Either type.
Yes, that would be nice. But I am suggesting this as a bug fix. This is a serious problem that makes it very awkward to handle a very common case. I am hoping for a fix that does not break currently non-broken programs. Here are two ways to fix it: 1. The bold approach: o Remove the implementation of fail in Monad Either o Remove the Error instance requirement o Possibly move the Monad Either instance to a different module, and just import it in Control.Monad.Error That implies that code using fail instead of throwError to throw an Error or, worse yet, implicitly throwing an Error with a failed pattern match, would be considered already broken. 2. The less bold but messier approach: Add a new monad to the standard library that looks just like Either, for non-Error calculations that need to exit with a value. As an additional option to either (1) or (2), add aliases to Either and ErrorT as a first step to replacing them with better names as Iavor suggests (and does in his alternative monad library). I think that the current situation, in which to do a calculation that is even slightly complex you have to either roll your own monad or use CPS, is not acceptable. I personally prefer (1). -Yitz