Skip to content

Add some safe optional prefix parser #113

@ogregoire

Description

@ogregoire

In the AGENTS.md, you write:

Use anyOf() to split the rule into two choices for an optional prefix:

anyOf(
    sequence(accidental, note, (a, n) -> n.withAccidental(a)),  // with prefix
    note)  // without prefix

My issue with this is that it's hard to use, and unintuitive, and yet it's documented as totally safe. I'm using this structure several times, unfortunately, and in this way:

anyOf(
  sequence(
    prefix,
    here()
      .I()
      .construct()
      .a()
      .quite()
      .long()
      .parser(),
    (pref, suff) -> ...),
  here()
    .I()
    .construct()
    .a()
    .quite()
    .long()
    .parser()
    .map(suff -> ...))

This leads to a lot of redundancy. Moving the pain point on the user. Okay, I could move my long parser to another variable, fair point:

Parser<X> quiteLongParser = here()
    .I()
    .construct()
    .a()
    .quite()
    .long()
    .parser();

anyOf(
  sequence(
    prefix,
    quiteLongParser,
    DomainObject::new),
  quiteLongParser
    .map(suff -> new DomainObject(DEFAULT_VALUE, suff))
)

The clear issue here becomes the duplication of the lambda. A lesser issue is the indenting that is not the same because of the sequence.

What if we could have a static <T, U, V> Parser<V> optionalPrefix(Parser<T>, Parser<U>, BiFunction<Optional<T>, U, V>? Even as a wrapper around that anyOf?

In my example, the only lambda I get is (Optional<T> t, U u) -> new DomainObject(t.orElse(DEFAULT_VALUE), u)), which is probably better looking and shows the intent more than the anyOf(sequence(), ) structure.

It's just a wrapper around the totally safe structure you provide that is easier to use than the current recommended structure. So I don't see any trouble in regards to the safety.

Do I miss anything? Would this be possible to implement?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions