英文:
How do I override error message on Left in Haskell?
问题
我想从文件中读取,并正在使用左/右模式匹配来判断所说的文件是否存在,如下所示:
tehfile <- readIniFile "somefile_that_does_not_exist.ini"
s <- case tehfile of
Left a -> print "woot"
Right b -> ...
我收到的错误是由Data.Ini库生成的:"openFile: 文件不存在(没有该文件或目录)"。
理想情况下,我想要完全覆盖该文本,或者至少在库生成的文本之后添加我的超级有用的 "woot" 字符串。我该如何做,为什么现在的代码中没有发生这种情况?
英文:
I want to read from file and am using pattern matching on Left/Right to tell is said file exists like so:
tehfile <- readIniFile "somefile_that_does_not_exist.ini"
s <- case tehfile of
Left a -> print "woot"
Right b -> ...
The error I'm getting is the one generated by Data.Ini library: "openFile: does not exist (No such file or directory)".
Ideally, I'd like to override that text entirely or at least append my super useful "woot" string after the one produced by the library. How can I do that and why doesn't it happen in the code I have now?
答案1
得分: 1
如果您查看 readIniFile
的实现,它只是:
readIniFile :: FilePath -> IO (Either String Ini)
readIniFile = fmap parseIni . T.readFile
首先,它尝试打开并读取文件,然后尝试将内容解析为 INI 配置。如果文件不存在,第一部分将失败并引发异常,第二部分将返回一个 Left
。要打印您自己的消息并继续计算,而不是在 Left
情况下进行模式匹配,您将想要使用 catch
处理异常。
λ> import Control.Exception
λ> handler :: IOException -> IO (Either String Ini); handler _ = putStrLn "woot" >> pure (Left "woot")
λ> tehfile <- readIniFile "somefile_that_does_not_exist.ini" `catch` handler
woot
或者,您可以抛出带有您自己消息的错误,以结束计算:
λ> handler :: IOException -> IO (Either String Ini); handler _ = error "woot"
λ> tehfile <- readIniFile "somefile_that_does_not_exist.ini" `catch` handler
*** Exception: woot
CallStack (from HasCallStack):
error, called at <interactive>...
或编写自己的异常并抛出:
λ> data Woot = Woot deriving (Show)
λ> instance Exception Woot
λ> handler :: IOException -> IO (Either String Ini); handler _ = throwIO Woot
λ> tehfile <- readIniFile "somefile_that_does_not_exist.ini" `catch` handler
*** Exception: Woot
只提供翻译的部分,没有其他内容。
英文:
If you look at the implementation for readIniFile
, it's just
readIniFile :: FilePath -> IO (Either String Ini)
readIniFile = fmap parseIni . T.readFile
First it tries to open and read the file, then it tries to parse the contents as an INI config. That first part would fail with an exception if the file doesn't exist, and the second fails with a Left
. To print your own message and resume the computation, instead of pattern matching on the Left
case you'll want to catch
the exception.
λ> import Control.Exception
λ> handler :: IOException -> IO (Either String Ini); handler _ = putStrLn "woot" >> pure (Left "woot")
λ> tehfile <- readIniFile "somefile_that_does_not_exist.ini" `catch` handler
woot
Or you can throw an error with your own message, to end the computation
λ> handler :: IOException -> IO (Either String Ini); handler _ = error "woot"
λ> tehfile <- readIniFile "somefile_that_does_not_exist.ini" `catch` handler
*** Exception: woot
CallStack (from HasCallStack):
error, called at <interactive>...
Or write your own exception and throw that
λ> data Woot = Woot deriving (Show)
λ> instance Exception Woot
λ> handler :: IOException -> IO (Either String Ini); handler _ = throwIO Woot
λ> tehfile <- readIniFile "somefile_that_does_not_exist.ini" `catch` handler
*** Exception: Woot
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论