gpt4 book ai didi

haskell - Haskell 库抛出异常背后的想法是什么

转载 作者:行者123 更新时间:2023-12-04 01:55:45 24 4
gpt4 key购买 nike

为什么库(例如 wreq 上的 404 )会抛出异常,而不是将结果包装成类似 Maybe 的东西? ?

天真地,我认为Maybe会更好(例如,如果我不处理所有情况,编译器会警告我)。为什么我在这里错了?

最佳答案

Haskeller 确实努力避免从函数中抛出异常——一个函数应该只在真正异常的情况下抛出异常,即在“这永远不应该发生”的情况下,比如用户传递一些文档明确禁止的输入。如果纯函数经常抛出异常,这将是一个大问题,不仅因为类型没有说明应该准备捕获什么,而且无法在纯函数中捕获异常,而只能在 IO 中捕获异常。调用函数的代码。即使您原则上可以捕获异常,也可能很难预测它需要在哪里完成,因为惰性评估会延迟它实际发生的时间点。

事实上,即使在例如 Wreq.get ,函数不会抛出异常。

Prelude Network.Wreq> get "htt:/p/this-isn't even valid URL syntax" `seq` "Ok"
"Ok"

它是 IO执行时抛出的 Action :
Prelude Network.Wreq> get "htt:/p/this-isn't even valid URL syntax" >> pure ()
*** Exception: InvalidUrlException "htt:/p/this-isn't%20even%20valid%20URL%20syntax" "Invalid scheme"

现在使用 IO行动起来,情况就有些不同了。很多 IO在难以或无法预测的不同情况下,操作可能会产生非常不同的错误,例如硬盘驱动器崩溃。为每个 Action 以合适的数据类型对所有可能的错误进行分类将是一项艰巨的任务,处理所有可能的情况或找出要传递的部分确实非常麻烦。并且简单地包装每个 IO 的结果 Maybe 中的操作只会导致类似于 Java 中的每个引用都可能为空的情况。这并不能告诉你任何事情,人们通常也不会想出明智的方法来处理这个问题。

这几乎就是为什么首先发明异常的问题,并且它适用于过程语言和 Haskell 一样(或者更确切地说,它是 IO 的过程 eDSL)。因为与纯函数不同, IO在它的控制流中确实有一个明确定义的时间序列,如果你需要捕获一些特定的异常,你必须在哪里做也很清楚。

这并不是说它对 IO 毫无意义。返回 Maybe 的操作/ Either使可能的错误显式化的值,但这并不总是值得的。

关于haskell - Haskell 库抛出异常背后的想法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52987652/

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