gpt4 book ai didi

haskell - 处理纯代码抛出的 `try`异常

转载 作者:行者123 更新时间:2023-12-02 21:29:16 24 4
gpt4 key购买 nike

我正在使用 Haskell 处理异常,并偶然发现了一件我尚无法理解的事情。

在 GHCi 中我这样做:

Prelude Control.Exception> let thrower = (read "A") :: Int
Prelude Control.Exception> :{
Prelude Control.Exception| let main = do
Prelude Control.Exception| x <- (try $ return thrower) :: IO (Either SomeException Int)
Prelude Control.Exception| print x
Prelude Control.Exception| :}
Prelude Control.Exception> main

这定义了 thrower,我的测试表达式将因异常而失败。

然后我定义 main 将该表达式包装到 try 中(首先将其包装到 IO 中,因为 try接受 IO),然后从 IO 中解开它(由 try 生成)并打印

到目前为止,一切看起来都很棒 - 在 repl 中评估 main 会返回包装在 Either 中的异常:

Right *** Exception: Prelude.read: no parse

但是,如果我尝试编译并执行与应用程序相同的代码:

module Main where

import Control.Exception

thrower = (read "A") :: Int

main = do
x <- (try $ return thrower) :: IO (Either SomeException Int)
print x

...它因异常而崩溃:

haskelltest.exe: Prelude.read: no parse

似乎异常已经过去了尝试

我在这里缺少什么以及处理这个问题的正确方法是什么?

最佳答案

嗯,基本上( as Sebastian Redl pointed out earlier )这是一个严格性问题。 return thrower 不会以任何方式评估 thrower,因此尝试成功。只有当 Either SomeException Int 的内容被打印出来,即 Right thrower 时,read 才会真正尝试解析 "A",然后失败了...但是此时,尝试已经结束了。

防止这种情况的方法是 inject the parse result strictly进入 IO monad,使用

main = do
x <- try $ evaluate thrower :: IO (Either SomeException Int)
print x

为什么 try 在 GHCi 中的代码失败,我不知道;我敢说不应该。 <子>啊哈:as Reid noted实际上并没有失败!

可以说,这是一个为什么在 Haskell 中通常应该避免异常的例子。 Use a suitable monad transformer明确可能发生的错误,并获得错误检查的可靠评估。

关于haskell - 处理纯代码抛出的 `try`异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31231542/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com