Search code examples
haskellexceptionmonad-transformers

How can I convert this function from ExceptT to Except in Haskell?


I got very confused with Except, specially since there is no good tutorial around the web. I don't know how can I convert this function from ExceptT to Except:

data Error = Empty deriving (Show)

badFunction :: ExceptT Error IO ()
badFunction = throwError Empty

main :: IO ()
main = do
    caught_result <- runExceptT badFunction
    case caught_result of
      Left _ -> putStrLn "caught some error"
      Right _ -> putStrLn "no errors were caught"

Solution

  • You write

    badFunction :: ExceptT Error IO ()
    badFunction = throwError Empty
    

    which suggests that it does IO. But it doesn't do any IO. As Willem Van Onsem points out, one option is to indicate that by using Except instead:

    badFunction :: Except Error ()
    

    By the definition of Except, this is identical to

    badFunction :: ExceptT Error Identity ()
    

    There is a third option:

    badFunction :: Monad m => ExceptT Error m ()
    

    This gives you full flexibility!

    runExcept badFunction :: Either Error ()
    runExceptT badFunction :: Monad m => m (Either Error ())
    

    So if you choose, you can write

    main :: IO ()
    main = do
        caught_result <- runExceptT badFunction
        case caught_result of
          Left _ -> putStrLn "caught some error"
          Right _ -> putStrLn "no errors were caught"
    

    Whatever you think is clearer.