gpt4 book ai didi

haskell - 如何将 IOError 异常与本地相关异常结合起来?

转载 作者:行者123 更新时间:2023-12-02 16:40:02 25 4
gpt4 key购买 nike

我正在构建一个 Haskell 应用程序,并试图弄清楚如何构建错误处理机制。在实际的应用程序中,我正在使用 Mongo 进行大量工作。但是,为此,我将通过对文件进行基本 IO 操作来进行简化。

因此,对于这个测试应用程序,我想读入一个文件并验证它是否包含正确的斐波那契序列,每个值用空格分隔:

1 1 2 3 5 8 13 21

现在,在读取文件时,许多事情实际上都可能是错误的,我将把所有这些都称为 exceptions in the Haskell usage of the word .

data FibException = FileUnreadable IOError
| FormatError String String
| InvalidValue Integer
| Unknown String

instance Error FibException where
noMsg = Unknown "No error message"
strMsg = Unknown

编写一个纯函数来验证序列并在序列无效的情况下抛出错误很容易(尽管我可能可以做得更好):

verifySequence :: String -> (Integer, Integer) -> Either FibException ()
verifySequence "" (prev1, prev2) = return ()
verifySequence s (prev1, prev2) =
let readInt = reads :: ReadS Integer
res = readInt s in
case res of
[] -> throwError $ FormatError s
(val, rest):[] -> case (prev1, prev2, val) of
(0, 0, 1) -> verifySequence rest (0, 1)
(p1, p2, val') -> (if p1 + p2 /= val'
then throwError $ InvalidValue val'
else verifySequence rest (p2, val))
_ -> throwError $ InvalidValue val

之后,我想要读取文件并验证序列的函数:

type FibIOMonad = ErrorT FibException IO

verifyFibFile :: FilePath -> FibIOMonad ()
verifyFibFile path = do
sequenceStr <- liftIO $ readFile path
case (verifySequence sequenceStr (0, 0)) of
Right res -> return res
Left err -> throwError err

如果文件格式无效(它返回 Left (FormatError "something"))或者文件的数字不按顺序排列(左(InvalidValue 15))。但如果指定的文件不存在,则会抛出错误。

如何捕获 readFile 可能产生的 IO 错误,以便将其转换为 FileUnread 错误?

顺便问一下,这是最好的方法吗?我看到了 verifyFibFile 的调用者不必设置两种不同的异常处理机制,而可以只捕获一种异常类型的优点。

最佳答案

您通常可以考虑 EitherTerrors 包。 http://hackage.haskell.org/packages/archive/errors/1.3.1/doc/html/Control-Error-Util.html有一个实用程序 tryIO 用于捕获 EitherT 中的 IOError,您可以使用 fmapLT 将错误值映射到您的自定义类型.

具体:

type FibIOMonad = EitherT FibException IO

verifyFibFile :: FilePath -> FibIOMonad ()
verifyFibFile path = do
sequenceStr <- fmapLT FileUnreadable (tryIO $ readFile path)
hoistEither $ verifySequence sequenceStr (0, 0)

关于haskell - 如何将 IOError 异常与本地相关异常结合起来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14166205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com