作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有人可以解释一下以下 ghci 中的行为与行之间的区别:
catch (return $ head []) $ \(e :: SomeException) -> return "good message"
"*** Exception: Prelude.head: empty list
catch (print $ head []) $ \(e :: SomeException) -> print "good message"
"good message"
最佳答案
让我们看看第一种情况会发生什么:
catch (return $ head []) $ \(e :: SomeException) -> return "good message"
head []
这是
return
编辑为
IO
行动。这个 thunk 不会抛出任何异常,因为它没有被评估,所以整个调用
catch (return $ head []) $ ...
(类型为
IO String
)产生
String
thunk 无一异常(exception)。仅当 ghci 之后尝试打印结果时才会发生异常。如果你试过
catch (return $ head []) $ \(e :: SomeException) -> return "good message"
>> return ()
"
开头的字符串。然后它会尝试评估字符串,这会导致异常,而这被打印出来。
return
与
evaluate
(这迫使它的论点到 WHNF)为
catch (evaluate $ head []) $ \(e :: SomeException) -> return "good message"
catch
内部进行评估这将引发异常并让处理程序拦截它。
catch (print $ head []) $ \(e :: SomeException) -> print "good message"
catch
部分当
print
试图检查
head []
因此它被处理程序捕获。
Control.Exception
已经有
evaluate
,这会强制插入其 WHNF。我们可以轻松地对其进行扩充以使其达到完整的 NF:
import Control.DeepSeq
import Control.Seq
import Control.Exception
import Control.Monad
toNF :: (NFData a) => a -> IO a
toNF = evaluate . withStrategy rdeepseq
catch
的严格变体强制对其 NF 执行给定操作:
strictCatch :: (NFData a, Exception e) => IO a -> (e -> IO a) -> IO a
strictCatch = catch . (toNF =<<)
strictCatch
而不是
catch
在您的第一个示例中,它按预期工作。
关于exception - 如何在 Haskell 中正确使用 Control.Exception.catch?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18052619/
我是一名优秀的程序员,十分优秀!