gpt4 book ai didi

haskell - Haskell 中的父类(super class)型

转载 作者:行者123 更新时间:2023-12-04 05:50:19 25 4
gpt4 key购买 nike

如果我在这里使用了错误的术语,请提前道歉。

Haskell 中概括两种或多种类型的惯用方式是什么,以便您可以推迟对它们进行模式匹配,同时避免样板代码?

举一个具体的例子:在我的应用程序中,我想传递执行过程中可能发生的错误。这些错误来自不同的模块,所以我不直接控制它们:

data ErrorCatA = WTFError String | OMGError String
data ErrorCatB = BadError Int | TerribleError Float

现在我想传递这些错误类别的某种形式的父类(super class)型,这样我就可以像这样处理它们:
handleError :: GenericError -> IO ()
handleError err =
putStrLn $ case err of
WTFError s -> "WTF?! " ++ s
OMGError s -> "OMG?! " ++ s
BadError i -> if i > 5 then "Really bad" else "Not that bad"
TerribleError f -> "Terrible! " ++ show f

这可能吗?

我通过创建这样的包装器类型来最接近:
data GenericError = CatA ErrorCatA | CatB ErrorCatB
class GError a where
wrap :: a -> GenericError

instance GError ErrorCatA where
wrap = CatA

instance GError ErrorCatB where
wrap = CatB

通过这样做,我可以轻松包装所有错误,如
handleError $ wrap $ WTFError "Woopsie"
但我需要更改 handleError匹配 CatA (WTFError s)等等

有没有更简单或更惯用的方式来处理这样的场景?

最佳答案

假设您有异常类型

data HttpException  -- from http-client package
data MyCustomError = WTFError String | OMGError String
data AnotherError = BadError Int | TerribleError Float

你想单独处理每一个,但一般来说。而不是在它们周围写一个 sum 类型
data AllErrors = A HttpException | B MyCustomError | C AnotherError

您真正想要的是处理每个异常。那么为什么不这样做呢?编写函数
handleHttpError    :: HttpException -> IO ()
handleCustomError :: MyCustomError -> IO ()
handleAnotherError :: AnotherError -> IO ()

然后写一个类
class HandledError e where
handleError :: e -> IO ()


instance HandledError HttpException where
handleError = handleHttpError

instance HandledError MyCustomError where
handleError = handleCustomError

instance HandledError AnotherError where
handleError = handleAnotherError

只需使用 handleError需要的地方。它与您所拥有的并没有什么不同,但是现在处理一种错误的逻辑并没有与处理另一种错误的逻辑混在一起。想想类(class)水平 handleError和你的 handleError . wrap 一样.

关于haskell - Haskell 中的父类(super class)型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23661793/

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