try package:tomland

The parser try p behaves like the parser p, except that it backtracks the parser state when p fails (either consuming input or not). This combinator is used whenever arbitrary look ahead is needed. Since it pretends that it hasn't consumed any input when p fails, the (<|>) combinator will try its second alternative even if the first parser failed while consuming input. For example, here is a parser that is supposed to parse the word “let” or the word “lexical”:
>>> parseTest (string "let" <|> string "lexical") "lexical"
1:1:
unexpected "lex"
expecting "let"
What happens here? The first parser consumes “le” and fails (because it doesn't see a “t”). The second parser, however, isn't tried, since the first parser has already consumed some input! try fixes this behavior and allows backtracking to work:
>>> parseTest (try (string "let") <|> string "lexical") "lexical"
"lexical"
try also improves error messages in case of overlapping alternatives, because Megaparsec's hint system can be used:
>>> parseTest (try (string "let") <|> string "lexical") "le"
1:1:
unexpected "le"
expecting "let" or "lexical"
Note that as of Megaparsec 4.4.0, string backtracks automatically (see tokens), so it does not need try. However, the examples above demonstrate the idea behind try so well that it was decided to keep them. You still need to use try when your alternatives are complex, composite parsers.