Я хочу разобрать серию любых 4 символов. Однако эти символы не должны формировать определенную строку ( "bb"
в примере ниже). Итак, "aaaa"
и "abcd"
в порядке, но ни "bbcd"
, ни "abbc"
не должны совпадать.
Я составил следующий парсер:
ntimes 4 (requireFailure (string "bb") *> anyChar)
Однако я заметил, что он "съедает" одиночные b
символов. Например.
parse (ntimes 4 (requireFailure (string "bb") *> anyToken)) "abcde"
приводит к ['a', 'c', 'd', 'e']
(однако он терпит неудачу на "bbcd"
и "abbc"
, как и ожидалось).
В качестве обходного пути я использовал собственную реализацию requireFailure
:
requireFailure' : Parser a -> Parser ()
requireFailure' p = do
isP <- p *> pure True <|> pure False
if isP then fail "argument parser to fail"
else pure ()
So
parse (ntimes 4 (requireFailure' (string "bb") *> anyToken)) "abcde"
дает ['a', 'b', 'c', 'd']
, как я и ожидал.
По-видимому, синтаксические анализаторы Lightyear откатываются по умолчанию, если только не вызывается commitTo
.
Итак, мой вопрос: почему библиотечная реализация requireFailure
не выполняет откат в случае сбоя аргумента и является ли это ожидаемым поведением?