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 String在acc一些IO检查,因为.
我现在明白我正在研究折叠可组合动作列表的方法.我遇到了这个问题,并了解了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