简体   繁体   中英

How can we interact with 2 MonadError constraints having 2 different error types?

Say I have a function

function1 :: (MonadError String m, MonadIO m) => m Int

function2 :: (MonadError Int m, MonadIO m) => m Int

and a function to transform Int into a String

renderException :: Int -> String

Is there a way to implement function3, which is reusing all 3 functions?

function3 :: (MonadError String m, MonadIO m) => m Int
-- add the results from function1, function2 and 
-- transform function2 error into a String

It turns out that I can use runExceptT :

-- runExceptT :: ExceptT e m a -> m (Either e a)
function3 :: (MonadError String m, MonadIO m) => m Int
function3 =
  do ei <- runExceptT function1
     a  <- either (throwError . show) pure ei
     b  <- function2
     return (a + b)

So there's a way out of the MonadError e "trap". On the other hand I don't know how to encapsulate this runExcept / either throwError pattern.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM