可扩展的错误

时间:2013-07-10 04:33:27

标签: haskell error-handling

用几个词来描述一个问题。猜猜我有一个算法来检查某些东西,并且根据算法,它可能会因稍有不同的错误而失败,例如:

data Error1 = Error1
data Error2 = Error2
data Error3 = Error3

class Algorithm a where
    type CanFailWith a :: *
    check :: Something -> Maybe (CanFailWith a)

instance Algorithm FirstAlgorithm where
    type CanFailWith FirstAlgorithm = Either Error1 Error2
    ...

instance Algorithm SecondAlgorithm where
    type CanFailWith SecondAlgorithm = Either Error1 (Either Error2 Error3)
    ...

这个选项对用户来说不是很友好,因为难以使用它的分支结构,例如

 testError (Left Error1)          = ...
 testError (Right (Left Error2))  = ...
 testError (Right (Right Error3)) = ...

三个错误看起来并不那么糟糕,但每次额外错误都值得。

错误可能是简单的总和类型:

 data Error = Error1
            | Error2
            | Error3

但是在这种情况下,我强迫用户在第一个算法中覆盖不可能的情况,这不会失败Error3

问题是:对于扩展错误,最终用户解决方案是否有任何常见且令人满意的简单方法?

1 个答案:

答案 0 :(得分:2)

你可以尝试这样的事情,每个算法都有自己的错误总和类型。

{-# LANGUAGE TypeFamilies #-}

class Algorithm a where
    data CanFailWith a :: *
    check :: a -> [Int] -> Maybe (CanFailWith a)

data FirstAlgo = FirstAlgo deriving (Show)

instance Algorithm FirstAlgo where
    data CanFailWith FirstAlgo = FError1 |  FError2
    check a x = Nothing

data SecondAlgo = SecondAlgo deriving (Show)

instance Algorithm SecondAlgo where
    data CanFailWith SecondAlgo = SError1 | SError2 | SError3
    check a x = Nothing


testError :: CanFailWith SecondAlgo -> ()
testError SError1 = ()
testError SError2 = ()
testError SError3 = ()