[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