Haskell中的纯错误处理要么:如何折叠错误的可能性?

And*_*rey 6 error-handling haskell exception-handling fold either

我主要对Eithermonad及其所有的uilitites感兴趣Control.Error.读错误-1.0:简化了错误处理,我确信纯错误应该与IO错误分开.这意味着error,fail,exitFailure是函数,其使用应减少到IO单子.纯计算可以并且创建条件错误,但是是确定性的.

目前,使用折叠,我得到一种情况,数组中的元素可能会生成条件错误,这使得整个计算不可满足.例如(使用Data.ConfigFile):

type CPError = (CPErrorData, String)
data CPErrorData = ParseError String | ...
type SectionSpec = String
type OptionSpec = String

instance Error CPError
instance Error e => MonadError e (Either e)

get :: MonadError CPError m => ConfigParser -> SectionSpec -> OptionSpec -> m a


dereference :: ConfigParser -> String -> Either CPError String
dereference cp v = foldr replacer v ["executable", "args", "title"]
 where
  replacer :: String -> Either CPError String -> Either CPError String
  replacer string acc = do
    res <- acc
    value <- get cp "DEFAULT" string
    return $ replace ("${" ++ string ++ "}") value res
Run Code Online (Sandbox Code Playgroud)

情况是:我使用的是具有复杂类型的acc,只是因为如果找不到单个元素进行替换,那么整个值是不可计算的.

我的问题是:这难看吗?有没有更好的方法呢?我有一个类型的一些令人讨厌公用事业EitherT CPError IO Stringacc一些IO检查,因为.

And*_*rey 6

我现在明白我正在研究折叠可组合动作列表的方法.我遇到了这个问题,并了解了Kleisli运算符:

dereferenceValue :: ConfigParser -> String -> Either CPError String
dereferenceValue cp v = do
  foldr (>=>) return (fmap replacer ["executable", "args", "title"]) v
 where
  replacer :: String -> String -> Either CPError String
  replacer string res = do
    value <- get cp "DEFAULT" string
    return $ replace ("${" ++ string ++ "}") value res
Run Code Online (Sandbox Code Playgroud)

可能这看起来有点像我的问题,但感觉更干净.特别是因为签名replacer.它没有收到Monad作为第二个参数,并且对代码的其他部分变得更有用.

编辑:

更简单:

dereferenceValue :: ConfigParser -> String -> Either CPError String
dereferenceValue cp v = do
  foldM replacer v ["executable", "args", "title"]
 where
  replacer :: String -> String -> Either CPError String
  replacer res string = do
    value <- get cp "DEFAULT" string
    return $ replace ("${" ++ string ++ "}") value res
Run Code Online (Sandbox Code Playgroud)

结论:学习使用Hoogle