
Given this function f :: MyMonad String f = do liftIO $ putStrLn "Please enter a file name: " name ← liftIO getLine hFile ← liftIO $ openFile name ReadMode content ← liftIO $ hGetContents hFile return $ content I would like to catch the error thrown by openFile and translate it to my own exception type. So first I tried this: hFile ← (liftIO $ openFile name ReadMode) `catch` λ_ → throwError (KnownErr "open failed") ..but it fails because the error handler is returning a different type then the "try block". Right? Then I tried this: f = do liftIO $ putStrLn "Please enter a file name: " name ← liftIO getLine hFile ← (liftIO $ openFile name ReadMode ↠ return.Right) `catch` λ_ → return (Left $ KnownErr "open failed") case hFile of Right handle → do content ← liftIO $ hGetContents hFile return $ content Left error → throwError error ...which also fails with Couldn't match expected type `ErrorT MyType IO t0' with actual type `IO a0' In a stmt of a 'do' expression: hFile <- (do { handle <- liftIO $ openFile name ReadMode; return (Right handle) }) `catch` \ _ -> return (Left $ KnownErr "open failed") Any help is appreciated. Thanks! Full code here: import Control.Monad.Error import System.IO data MyType = UnknownErr | KnownErr String deriving (Show) instance Error MyType where noMsg = UnknownErr strMsg str = KnownErr str type MyMonad = ErrorT MyType IO main = do r ← runErrorT f reportResult r f :: MyMonad String f = do liftIO $ putStrLn "Please enter a file name: " name ← liftIO getLine hFile ← liftIO $ openFile name ReadMode content ← liftIO $ hGetContents hFile return $ content reportResult (Right c) = putStrLn ("The content is " ⊕ c) reportResult (Left e) = putStrLn ("Error: " ⊕ (show e))