haskell - 为什么这个 try catch 示例不起作用

标签 haskell exception

我有以下来自 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 ,但正如文档所说:

The catchIOError function establishes a handler that receives any IOException raised in the action protected by catchIOError. An IOException is caught by the most recent handler established by one of the exception handling functions. These handlers are not selective: all IOExceptions are caught.

(...)

Non-I/O exceptions are not caught by this variant; to catch all exceptions, use catch from Control.Exception.

因此,您可以使用 catchIOError 解决这里的问题(因为您正在处理 IOError,但如文档中所述,这仅涵盖了有限的一组异常(exception)),或者您可以从 Control.Exception 导入 catch:

<b>import Control.Exception(catch)</b>

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

main :: IO ()
main = toTry `<b>catch</b>` 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/

相关文章:

c++ - 使用 GHC 64 位构建的普通 Windows DLL 不链接

haskell - 为 MultiParamTypeClasses 注释不明确的类型变量

haskell - 在Windows中编译Haskell程序: is it possible without downloading something such as Cygwin?

android - 字符串值的 java.lang.NumberFormatException

exception - 应用程序运行一段时间后Pyspark套接字超时异常

java - Android 应用程序不断崩溃

java - 如何确保长时间运行的 Java 线程永不消亡

haskell - 为什么我必须按字段强制此数据类型,而不是一次全部强制?

dictionary - Haskell Data.Map 同时查找和删除

c# - StringBuilder.ToString() 抛出 'Index out of range' 异常