
So if I understand correctly, when the compiler sees this class definition:
For example, throwError in in the MonadError class definition:
class Monad m => MonadError e m | m -> e where throwError :: e -> m a
Then it sees this instance:
Instances:
Error e => MonadError e (Either e)
Because (Either e) is a monad, it "fits with" the m in the class definition. (The m has the constraint Monad on it.) Knowing that, the compiler uses the functional dependency to conclude that the given instance is the only possible instance. Is that right? Another question: in Control.Monad.Error, I see the instance MonadError IOError IO which leads to the question: apparently I can throw errors in the IO monad using throwError. But there is also throw and throwIO. What is the difference? Thanks, Mike