从hGetContents中检测惰性字符串中的I/O异常?

Dav*_*ter 3 error-handling haskell

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)
Run Code Online (Sandbox Code Playgroud)

如果在读取文件的第一行时发生异常,则此程序将打印字符数,直到发生I/O异常.相反,我希望程序崩溃并使用适当的I/O异常.如何修改此程序以具有该行为?

编辑:仔细检查hGetContents实现后,似乎不会忽略I/O异常,而是通过调用纯函数代码冒泡到触发评估的任何IO代码,然后有机会处理它.(我以前没有意识到纯函数代码会引发异常.)因此,这个问题是一个误解.

旁白:如果通过经验验证这种特殊行为,那将是最好的.不幸的是,很难模拟低级I/O错误.

Nik*_*kov 5

Lazy IO 被认为是许多haskellers 的陷阱,因此建议远离.你的案例多彩地描述了原因.

有一种非懒惰的hGetContents功能替代品.它起作用Text,但Text也是一般的首选替代品String.为方便起见,有现代的前奏曲,取而代之的StringText:基本前奏曲优雅前奏曲.