Haskell 对'的异常处理;readFile';

Haskell 对'的异常处理;readFile';,haskell,file-io,error-handling,handler,Haskell,File Io,Error Handling,Handler,我正在尝试向readFile函数添加一个简单的处理程序: readHandler :: IOError -> IO () readHandler e | isDoesNotExistError e = putStrLn "The file does not exist" | otherwise = putStrLn "Something went wrong" main = do // stop executing if there is no fil

我正在尝试向
readFile
函数添加一个简单的处理程序:

readHandler :: IOError -> IO ()  
readHandler e  
    | isDoesNotExistError e = putStrLn "The file does not exist"
    | otherwise = putStrLn "Something went wrong"  

main = do
    // stop executing if there is no file   
    contents <- (readFile "path.xml") `catch` readHandler
    // generates [(x,y),(x,y)]
    coordinates = parseXML contents
    // I want to do something with the coordinates
    nextFunction coordinates
readHandler::IOError->IO()
readHandler e
|ISDOESNOTEXTISTERROR e=putStrLn“文件不存在”
|否则=putStrLn“出了问题”
main=do
//如果没有文件,请停止执行

contentsreadHandler的
catch(readFile“path”)类型应该是什么

显然,如果文件存在,我们希望它是一个
字符串
catch
不应该更改它的类型,因此无论如何我们都必须生成一个
字符串
。因为如果抛出异常,
readHandler
将运行,它还必须生成一个字符串

通过这种方式,
catch
就像一个非常复杂的
if
表达式:)但是,这并不理想,因为我们不想继续使用一些非文件中的随机
字符串运行函数

相反,我们可以这样做

 main = handle readHandler $ do
    ...
因为现在我们只需要生成一个
IO()
,非常简单

如果你的船因为任何原因不能浮起来,另一个明智的选择是将这个令人恼火的异常转化为一个更令人愉快的
other

 main = do
   strOrExc <- try $ readFile "foo"
   case strOrExc of
     Left except -> print except
     Right contents -> putStrLn contents
捕获有类型

catch :: Exception e => IO a -> (e -> IO a) -> IO a
因此,如果catch的第一个参数是
iostring
,那么第二个参数(它是一个函数)也必须返回该参数。 您可以这样更改readHandler:

readHandler :: IOError -> IO String
readHandler e  
    | isDoesNotExistError e = do putStrLn "The file does not exist" ; return ""
    | otherwise = do putStrLn "Something went wrong" ; return ""

但我不确定这是否是想要的“副作用”(返回空字符串)。

这是可行的,但我需要程序停止,而不是返回空字符串。我认为应该有更好的方法。我编辑了我的代码以使其更清晰。有没有办法在我的处理程序中使用第二个解决方案,并在找到文件后继续执行我的执行链?@Gert Jan Sure,在这种情况下,不要只打印字符串,而是将您想要使用的字符串放在分支中。这当然很难看。一个不合理的方法是
other
monad。现在的问题是'strOrExc'的类型是'other a0 String'而不是'String'。我认为我对Haskell的了解还不足以解决这个问题。谢谢你的帮助!:)@Gert Jan当然,问题是你有“other”“一个异常或
字符串
,即
案例
让您进行模式匹配并访问
字符串
,在我的示例中,它被称为contents,现在我得到的是“没有因使用“print”(以及一些其他错误)而产生的实例(Show a0))。我打算在这里停下来,也许明天再试一次。。我相信你的答案是正确的,我感谢你的帮助!
catch :: Exception e => IO a -> (e -> IO a) -> IO a
readHandler :: IOError -> IO String
readHandler e  
    | isDoesNotExistError e = do putStrLn "The file does not exist" ; return ""
    | otherwise = do putStrLn "Something went wrong" ; return ""