Gilgamesz
Gilgamesz

Reputation: 5073

Understanding the ErrorT monad transformer

newtype ErrorT e m a = ErrorT { runErrorT :: m (Either e a) }

instance (Monad m, Error e) => Monad (ErrorT e m) where

    return a = ErrorT $ return (Right a)

    m >>= k = ErrorT $ do
        a <- runErrorT m
        case a of
            Left l -> return (Left l)
            Right r -> runErrorT (k r)

    fail msg = ErrorT $ return (Left (strMsg msg))

Let's consider above piece of code. It makes me trouble to understand it. How does it work in context of Monads/Transormer Monads? Especially, the problem is understanding why return a = ErrorT $ return (Right a) return return (Right a). I don't understand why just it.

The second issue. m >>= k is basically understood by me ( I hope so ;) )but why in Right r -> runErrorT (k r) appeared runError?

Upvotes: 0

Views: 106

Answers (1)

chi
chi

Reputation: 116139

ErrorT is just a wrapper. That is, the type ErrorT e m a is isomorphic to the type m (Either e a): the latter can be converted into the former by the constructor ErrorT, while its associated destructor runErrorT converts in the other direction.

The definitions of return and >>= must wrap/unwrap values to respect the types. This wrapping/unwrapping has no concrete effect at run time, it is just there so that the program type checks and the compiler can choose the correct monad instance (m or ErrorT e m, depending on whether a value it's wrapped).

Here

return a = ErrorT $ return (Right a)

the part return (Right a) has type m (Either e a), but we want ErrorT e m a instead. Applying ErrorT fixes that.

Similarly, in this code:

m >>= k = ErrorT $ do
    a <- runErrorT m
    case a of
        Left l -> return (Left l)
        Right r -> runErrorT (k r)

we need to return ErrorT m e b. This is done by using ErrorT applied to some value of type m (Either e b). The part Left l has type Either e b, so return adds the last m on top. Instead the part k r has type ErrorT e m b, so we need to unwrap it with runErrorT (so that the whole do can be rewrapped again).

Upvotes: 3

Related Questions