Raise error error value to transformer MONT MONT

I think I lack a basic understanding of monad transformers because I found myself writing this code:

import Control.Monad.Identity
import Control.Monad.Error

liftError :: Either String Int -> ErrorT String Identity Int
liftError x = do case x of
                    Right val -> return val
                    Left err -> throwError err

gateway :: Bool -> ErrorT String Identity Int
gateway = liftError . inner

inner :: Bool -> Either String Int
inner True = return 5
inner False = throwError "test"

While this works, I think it can be done more elegantly. In particular, I am looking for a replacement liftError, which, I think, I do not need to determine for myself.

What is the easiest way to make gatewayand innerwork together without changing their type?

+5
source share
1 answer

If you just change the types a bit, you don’t have to raise at all.

{-# LANGUAGE FlexibleContexts #-}

gateway :: Bool -> ErrorT String Identity Int
gateway = inner

inner :: MonadError String m => Bool -> m Int
inner True = return 5
inner False = throwError "test"

MonadErrorhas instances for ErrorTboth and for Either, so you can use innerboth.

+6
source

All Articles