liveBook · Manning

Attempt combinator

As explained in Functional Programming in Scala, Second Edition

A parser operation that reverses a parser's commitment on failure so that an alternative branch can be tried.

An attempt combinator reverses a parser’s commitment when that parser fails, allowing an alternative branch to retry the same input. It is useful when several tokens must be examined before a grammar branch becomes unambiguous. section 9.5.3

The combinator coordinates alternatives through three rules:

  • A parser normally commits after examining input; a committed failure stops the alternative chain. section 9.6.4
  • attempt converts committed failures into uncommitted failures, so the next parser can run on the original input. section 9.6.4
  • The implementation can avoid unnecessary branches while still permitting backtracking where grammar ambiguity requires it. section 9.5.3

Choosing between similar prefixes

For input "abra cadabra!", a branch parsing "abra" followed by spaces and another "abra" may fail only after consuming the shared prefix. Wrapping that branch in attempt lets the alternative "abra" followed by spaces and "cadabra!" retry; commitment occurs only after the ambiguous branch succeeds. section 9.5.3

extension [A](p: Parser[A]) def attempt: Parser[A] =
  l => p(l).uncommit
 
enum Result[+A]:
  ...
  def uncommit: Result[A] = this match
    case Failure(e, true) => Failure(e, false)
    case _ => this

Implement attempt by applying uncommit to the parser result, changing only committed failures while preserving successes and uncommitted failures. section 9.6.4

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Explains commitment semantics, a concrete ambiguous parse, and a functional implementation using committed failure state.
Examples
Uses competing parsers for "abra cadabra" and "abra abra", plus an implementation based on Result.uncommit.
What it assumes
Assumes parser alternatives and committed versus uncommitted failures, while showing how those states govern or.
What you can do after
Apply attempt to permit controlled backtracking in ambiguous parser alternatives.
How it connects
Connects parser combinators with alternatives, backtracking, parse errors, and parser result types.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Programming in Scala, Second Edition. The section links point to the parts of the book it draws on.