用几个词来描述一个问题。猜猜我有一个算法来检查某些东西,并且根据算法,它可能会因稍有不同的错误而失败,例如:
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
问题是:对于扩展错误,最终用户解决方案是否有任何常见且令人满意的简单方法?
答案 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 = ()