ファイルが存在する場合はファイルを安全に読み取り、ファイルが存在しない場合は何もしない単純な関数を作成しようとしています。
safeRead :: String -> IO ()
safeRead path = readFile path `catch` handleExists
where handleExists e
| isDoesNotExistError e = return ()
| otherwise = throwIO e
これはコンパイル時に失敗します
Couldn't match type ‘[Char]’ with ‘()’
Expected type: IO ()
Actual type: IO String
In the first argument of ‘catch’, namely ‘readFile path’
In the expression: readFile path `catch` handleExists
であるため、これは理にかなって:t readFile
いますreadFile :: FilePath -> IO String
。を返す関数IO String
など (とIO String
同じではありませんIO ()
)
署名の変更String -> IO String
Couldn't match type ‘()’ with ‘[Char]’
Expected type: IOError -> IO String
Actual type: IOError -> IO ()
In the second argument of ‘catch’, namely ‘handleExists’
In the expression: readFile path `catch` handleExists
handleExists には型があるので、これも理にかなっていますIO ()
全員のルックアップを保存するには、catch を次のようにインポートします。catch
import Control.Exception
のシグネチャは次のとおりです。
catch :: Exception e => IO a -> (e -> IO a) -> IO a
私の本当の質問は、この種のエラーセーフで柔軟なコードを Haskell で書くにはどうすればよいかということです。より具体的には、成功ケースと失敗ケースの両方を処理できるようにするには、この関数にどのような変更を加える必要があるでしょうか?