我有以下来自here的演示代码:

import System.Environment
import System.IO
import System.IO.Error

main = toTry `catch` handler

toTry :: IO ()
toTry = do (fileName:_) <- getArgs
           contents <- readFile fileName
           putStrLn $ "The file has " ++ show (length (lines contents)) ++ " lines!"

handler :: IOError -> IO ()
handler e = putStrLn "Whoops, had some trouble!"

但这给了我错误:
runghc trycatch2.hs

trycatch2.hs:5:14: error:
    Variable not in scope: catch :: IO () -> (IOError -> IO ()) -> t

问题在哪里,如何解决?谢谢。

最佳答案

Learn You a Haskell for the Greater Good中的示例已过时, catch :: Exception e => IO a -> (e -> IO a) -> IO a 函数是 Control.Exception 的一部分。

但是 System.IO.Error 仍然具有适用于此处的catch函数: catchIOError :: IO a -> (IOError -> IO a) -> IO a ,但正如文档所述:

catchIOError函数建立一个处理程序,以接收在IOException保护的操作中引发的任何catchIOError。 IOException被其中一个异常处理函数建立的最新处理程序捕获。这些处理程序不是选择性的:捕获所有IOExceptions

(...)

变体未捕获非I / O异常;要捕获所有异常,请使用catch中的Control.Exception

因此,您可以在此处使用catchIOError来解决此问题(因为您正在处理IOError,但是按照文档中的说明,这仅涵盖了有限的一组例外),或者您可以从catch导入Control.Exception:

import Control.Exception(catch)

import System.Environment
import System.IO
import System.IO.Error

main :: IO ()
main = toTry `catch` handler

toTry :: IO ()
toTry = do (fileName:_) <- getArgs
           contents <- readFile fileName
           putStrLn $ "The file has " ++ show (length (lines contents)) ++ " lines!"

handler :: IOError -> IO ()
handler e = putStrLn "Whoops, had some trouble!"

关于haskell - 为什么这个try catch示例不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56218488/

10-10 15:03