避免在 Parsers 库的解析器中使用 fail
Avoiding usage of fail in parsers from Parsers library
据我所知,不推荐使用 fail,稍后将被删除。
在下面的Parsers/Trifecta例子中应该正确使用什么而不是失败?
parserNaturalNoLeadZero :: Parser Integer
parserNaturalNoLeadZero = do
digits <- some digit
if length digits > 1 && head digits == '0'
then fail "Leading Zeros"
else return $ read digits
如文档所述,正在引入新的 MonadFail
class 来履行该职责。
但是,对于像解析器这样的东西,明智的选择通常是 empty
,它已经存在了很长时间。
秒差距:
三连胜:
唯一的区别是它们产生的错误信息。
对意外标记使用 unexpected
。 unexpected "token"
将导致类似 "unexpected: 'token'"
.
的错误消息
用 high-level 结构注释解析器,它们使用 (<?>)
.
This is normally used at the end of a set alternatives where we want to return an error message in terms of a higher level construct rather than returning all possible characters.
parseExpr = ... <?> "expression"
parseId = ... <?> "identifier"
parseTy = ... <?> "type"
empty
不会产生任何错误消息。回溯并让另一个分支成功或负责报告有意义的错误仍然有用。
对其他类型的错误使用 fail
,图书馆不能对其中的内容做出太多假设,因此他们可能会将其参数视为原始消息。
据我所知,不推荐使用 fail,稍后将被删除。
在下面的Parsers/Trifecta例子中应该正确使用什么而不是失败?
parserNaturalNoLeadZero :: Parser Integer
parserNaturalNoLeadZero = do
digits <- some digit
if length digits > 1 && head digits == '0'
then fail "Leading Zeros"
else return $ read digits
如文档所述,正在引入新的 MonadFail
class 来履行该职责。
但是,对于像解析器这样的东西,明智的选择通常是 empty
,它已经存在了很长时间。
秒差距:
三连胜:
唯一的区别是它们产生的错误信息。
对意外标记使用
unexpected
。unexpected "token"
将导致类似"unexpected: 'token'"
. 的错误消息
用 high-level 结构注释解析器,它们使用
(<?>)
.This is normally used at the end of a set alternatives where we want to return an error message in terms of a higher level construct rather than returning all possible characters.
parseExpr = ... <?> "expression" parseId = ... <?> "identifier" parseTy = ... <?> "type"
empty
不会产生任何错误消息。回溯并让另一个分支成功或负责报告有意义的错误仍然有用。对其他类型的错误使用
fail
,图书馆不能对其中的内容做出太多假设,因此他们可能会将其参数视为原始消息。