choice<E, A> function
Try alternatives in order until one succeeds.
When every alternative starts with a known, distinct character (e.g.
null / true / false / [ / { / " / digits in JSON), the
builder transparently fuses to a FirstCharChoice for O(1) dispatch
instead of the linear Or-chain scan. The fusion is conservative:
any alternative whose leading-char set is undecidable (Defer,
FlatMap, Memo, an opaque Satisfy, etc.), or any pair of
alternatives that share a leading char, disables it and falls
through to a regular Choice. Choices with fewer than 3
alternatives are also left unfused — a 2-way choice is already
efficiently handled by the existing Or FIRST-set optimization.
Implementation
Parser<E, A> choice<E, A>(List<Parser<E, A>> alternatives) {
if (alternatives.length < 3) return Choice<E, A>(alternatives);
final fused = _tryFuseFirstChar<E, A>(alternatives);
if (fused != null) return fused;
return Choice<E, A>(alternatives);
}