IO エラー処理

Haskell のエラー処理と言うと、ErrorT だかなんだかで「たかがエラー処理で、なんでこんなにややこしいことを覚えねばならんのだ」と投げ出したくなるのだけど、IO エラーに限ればけっこう簡単。

Either でラップして結果を受けとる try と、エラーハンドラを直接渡す catch のどちらかを使えば大体こと足りる。

import IO (try, catch, stderr, hPrint)
import System.Directory (getPermissions, readable)

-- try 版.
readablePath :: FilePath -> IO Bool
readablePath path = do ret <- try (getPermissions path)
                       case ret of
                         (Left error) -> hPrint stderr error >>
                                         return False
                         (Right p)    -> return (readable p)

-- catch 版.
readablePath' :: FilePath -> IO Bool
readablePath' path = catch (getPermissions path >>= return . readable)
                           (\error -> hPrint stderr error >> return False)