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

标签 haskell types

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

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/

相关文章:

Haskell 读取 args 值

Haskell MonadState 实现 put 和修改

optimization - Foldl 是尾递归,那么为什么foldr 运行得比foldl 快呢?

JavaScript请解释一下这个语法

postgresql - 如何解决 Postgres 中的错误 42883?

list - Haskell对函数调用感到沮丧

haskell - 如何在 Haskell 中使用额外的类型来获得额外的类型安全

Haskell 编译 IO-Action 顺序和刷新

haskell - 为什么在 Haskell 的情况下别名函数会降低性能

typescript - 字符串文字解析需要空格才能工作