gpt4 book ai didi

haskell - 优雅的 Haskell 案例/错误处理

转载 作者:行者123 更新时间:2023-12-03 20:37:54 25 4
gpt4 key购买 nike

我试图更好地理解如何在 haskell 中处理错误情况,并编写了一些代码来帮助我解决这个问题。

是否有更好的方法(更优雅、更短、更通用)来处理多种替代方案(如嵌套 case 表达式)?关于该主题的任何不错的教程?

此示例的虚构类型。
这有点简化,因为大多数情况下不仅有这些嵌套
类型,但依赖值只能按顺序检索(例如
从标准输入读取一个 id,然后从一个
数据库)。所以这里的嵌套应该演示这样一种情况,即只有在已经检查了外部值 Nothing 时,内部值才可用。 .请看我的new question举个更好的例子。

type MyType = (Maybe (Maybe Int))

目标

在小于 10 时返回 int,在其他情况下(大于或
等于 10,Nothing 或 Just Nothing)返回不同的错误消息。
process Nothing ~> "error"
process (Just Nothing) ~> "error2"
process (Just (Just 20)) ~> "error3"
process (Just (Just 5)) ~> "5"

到目前为止尝试过:

天真的实现。

遭受“爬行压痕”
process :: MyType -> String
process t = case t of
Nothing -> "error"
Just a -> case a of
Nothing -> "error2"
Just b -> if b < 10 then show b else "error3"

也许功能

使用 Maybe 功能,这使它更短但也更难阅读。
process2 :: MyType -> String
process2 t = maybe "error" (\a -> maybe "error2" (\b -> if b < 10 then show b else "error3") a) t

模式匹配

迄今为止最好的解决方案,但在更复杂的情况下是不可能的
案例(见 MyType 类型定义上面的注释)。
process3 :: MyType -> String
process3 Nothing = "error"
process3 (Just Nothing) = "error2"
process3 (Just (Just a))
| a < 10 = show a
| otherwise = "error3"

可以在 https://gist.github.com/4024395 下找到带有代码的要点

最佳答案

嵌套 Maybes确实很乱。

建议1:滚动自定义错误类型并使用Either

data MyError = ReadError | TooBig Int

explain :: MyError -> String
explain ReadError = "Error: the requested Int could not be found"
explain TooBig i = "Error: the supplied Int should be at most 10, but it was " ++ show i

现在使用 Either 混合 Ok 值(右)和错误值(左):
type MyType = Either MyError Int

现在有很多方便的功能,如 either以及 Either a 的 Applicative 和 Monad 实例让编写漂亮的代码变得容易:
myAdd :: MyType -> MyType -> MyType
myAdd i1 i2 = (+) <$> i1 <*> i2

非常适用,或者
myMult i1 i2 = do
a <- i1
b <- i2
return $ a * b

如果你更喜欢一元符号。
我们可以使用 either以程序崩溃的方式
myShow :: MyType -> String
myShow = either (error.explain) show

或告诉我无论如何:
process4 :: MyType -> String
process4 = either explain show

建议2:滚动自定义类型
data MyType' = OK Int | ReadError | TooBig Int

并使用模式匹配。在我看来,这不如建议 1 好,因为你失去了高阶函数重用,但它比 Maybe (Maybe Int) 更好

建议 3:使用 Error monad

阅读 Control.Monad.Error并使用提供的函数或 ErrorT单子(monad)变压器。

关于haskell - 优雅的 Haskell 案例/错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13251388/

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