haskell - Haskell 中的纯错误处理,带有 : how to fold with error possibility?

标签 haskell exception-handling error-handling fold either

我主要对 Either 感兴趣monad 和所有它的 uilitites 来自 Control.Error .阅读 errors-1.0: Simplified error handling ,我确信应该将纯错误与 IO 错误分开。这意味着 error , fail , exitFailure是应简化为 IO monad 的函数。纯计算可以并且将会产生条件错误,但是是确定性的。

目前,与 合作折叠 ,我遇到了一种情况,数组中的元素可能会产生条件错误,从而使整个计算无法满足。例如(使用 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

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

我的问题是:这丑吗? 有没有更好的方法来做到这一点? 我有一些 EitherT CPError IO String 类型的更糟糕的实用程序在 acc因为一些 IO 检查。

最佳答案

我现在明白我正在寻找一种折叠可组合 Action 列表的方法。我遇到了this问题,了解了Kleisli运算符(operator):

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

可能,这看起来有点像我的问题,但感觉更干净。特别是因为 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

结论:学会使用Hoogle

关于haskell - Haskell 中的纯错误处理,带有 : how to fold with error possibility?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23984923/

相关文章:

c++ - 在 main(...) 中捕获异常是否有意义?

function - 无法在 map 函数中捕获异常

error-handling - Teradata SP中的错误处理

php - 引用 - 这个错误在 PHP 中意味着什么?

haskell - 我的 sqrt 函数无法在 GHCi 中编译

haskell - 将 Coq 提取到 Haskell

haskell - Haskell 中 `foldl` 和 `foldr` 的数字问题

c++ - 异常处理(限制异常)

javascript - AdSense graphics.js TypeError

haskell - 使输入变量可从整个代码访问