1

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

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

一个问题是:是否有任何常见且可取的简单的最终用户解决方案来扩展错误?

4

1 回答 1

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 = ()
于 2013-07-10T06:11:48.063 回答