Class definition in the Error Monad

The All About Monads page on the Haskell Wiki gives this definition for the error monad:

class Error a where
  noMsg :: a
  strMsg :: String -> a

class (Monad m) => MonadError e m | m -> e where
  throwError :: e -> m a
  catchError :: m a -> (e -> m a) -> m a

instance MonadError (Either e) where
  throwError = Err
  (Err e) `catchError` handler = handler e
      a    `catchError` _       = a

I do not understand this fully, especially the line

class (Monad m) => MonadError e m | m -> e where

What does this mean?

I think the Error typeclass is a relic, and no longer used. As for the question,

class (Monad m) => MonadError e m | m -> e where

This is a declaration of a multi-parameter typeclass, MonadError e m. The prefix (Monad m) => is like a superclass - in order to be a MonadError e, m has to be a Monad first.

The second part m -> e is more interesting. It’s called a functional dependency, and means that type m must uniquely determine type e. Think of m = Either e - here indeed, m determines e. What’s more, it also means there can’t be many MonadError e instances for the same m monad.

1 Like

class ... => MonadError e m

This defines a class called MonadError with two type parameters, e and m

(Monad m) =>

An instance can only be defined for MonadErrror e m if there’s already a Monad instance for m

m -> e

and no two instances for MonadErrror e m may have the same m unless they have the same e

2 Likes