[Haskell-beginners] how to catch the error thrown by openFile?

Ovidiu Deac ovidiudeac at gmail.com
Sat Sep 24 19:52:24 CEST 2011


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))



More information about the Beginners mailing list