Haskellで例外処理の初歩
import System.Environment (getArgs) import Control.Exception (catch, SomeException) main :: IO () main = do args <- getArgs out <- catch (readFile $ head args ) (\_ -> return "error") print out
test$ runghc test02.hs test02.hs1 test02.hs:17:10: No instance for (GHC.Exception.Exception e0) arising from a use of `catch' The type variable `e0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there are several potential instances: instance GHC.Exception.Exception GHC.Exception.ArithException -- Defined in `GHC.Exception' instance GHC.Exception.Exception GHC.Exception.ErrorCall -- Defined in `GHC.Exception' instance GHC.Exception.Exception SomeException -- Defined in `GHC.Exception' ...plus 7 others In a stmt of a 'do' block: out <- catch (readFile $ head args) (\ _ -> return "error") In the expression: do { args <- getArgs; out <- catch (readFile $ head args) (\ _ -> return "error"); print out } In an equation for `main': main = do { args <- getArgs; out <- catch (readFile $ head args) (\ _ -> return "error"); print out }
型が曖昧ということらしい。 catchの型を確認してみる。
Prelude> :t Control.Exception.catch Control.Exception.catch :: GHC.Exception.Exception e => IO a -> (e -> IO a) -> IO a
型を明示した関数を用意してみる
import System.Environment (getArgs) import Control.Exception (catch, SomeException) notifyError :: SomeException -> IO String notifyError _ = return "error" main :: IO () main = do args <- getArgs out <- catch (readFile $ head args ) notifyError print out ~
# エラー系 test$ runghc test02.hs test02.hs1 "error" # 正常系 test$ runghc test02.hs test02.hs "import System.Environment (getArgs)\nimport Control.Exception (catch, SomeException)\n\nnotifyError :: SomeException -> IO String\nnotifyError _ = return \"error\"\n\nmain :: IO ()\nmain = do\n args <- getArgs\n-- file <- readFile ( head args )\n-- print file\n-- print $ readFile ( head args ) \n-- readFile ( head args ) >>= (\\x -> print x)\n-- out <- catch (readFile $ head args ) (\\e -> print e::SomeException >> return \"\" ) \n-- out <- catch (readFile $ head args ) (\\(e::SomeException) ->return \"\") \n-- out <- catch (readFile $ head args ) (\\err -> print (err::SomeException) >> return \"\") \n-- out <- catch (readFile $ head args ) (\\_ -> return \"error\") \n out <- catch (readFile $ head args ) notifyError \n print out\n" (root)MacBook-Air:test ogawanaoto$