hGetContentsは、ファイル ハンドルから読み取るために純粋に機能的なコードで使用できる遅延 String オブジェクトを返します。この遅延文字列の読み取り中に I/O 例外が発生した場合、基になるファイル ハンドルはサイレントに閉じられ、遅延文字列に追加の文字は追加されません。
この I/O 例外はどのように検出できますか?
具体的な例として、次のプログラムを考えてみましょう。
import System.IO -- for stdin
lengthOfFirstLine :: String -> Int
lengthOfFirstLine "" = 0
lengthOfFirstLine s = (length . head . lines) s
main :: IO ()
main = do
lazyStdin <- hGetContents stdin
print (lengthOfFirstLine lazyStdin)
ファイルの最初の行の読み取り中に例外が発生した場合、このプログラムは I/O 例外が発生するまでの文字数を出力します。代わりに、適切な I/O 例外でプログラムをクラッシュさせたいのです。このプログラムをどのように変更して、その動作をさせることができますか?
編集: hGetContents の実装を詳しく調べると、I/O 例外は無視されず、純粋な機能コードの呼び出しから、たまたま評価をトリガーした IO コードにバブル アップし、それを処理する機会があるように見えます。(純粋な機能コードが例外を発生させる可能性があることを以前は知りませんでした。) したがって、この質問は誤解です。
余談ですが、この例外的な振る舞いが経験的に検証されれば最高です。残念ながら、低レベルの I/O エラーをシミュレートすることは困難です。