///| ParserLike — 解析器扩展点的通用组合子集。

///| MoonBit 中 `Parser[T]` 本质是 `(State) -> ParseResult[T]` 的函数包装,

///| 因此"任何能给出该函数的自定义类型"都可以直接接入 astrolabe 组合子:

///|

///| - 直接传裸运行函数:`@astrolabe.pmap(my_run_fn, f)`

///|   (`my_run_fn : (State) -> ParseResult[A]`)

///| - 包装类型暴露 `run_fn(self)` 方法后同理(见 `examples/ext` 的 `Traced[T]`)

///|

///| 典型扩展场景:带调用日志/计数的包装解析器、缓存/memoized 解析器、

///| 与其他解析库的适配层。

///|

///| 设计说明:MoonBit 的 trait 不支持"实现类型与结果类型分离"的参数化

///| (`trait ParserLike[A]` 不合法),因此本扩展点采用函数式约定 —

///| 这也是 MoonBit 惯用的扩展方式(`Parser::of` 即同一扩展点)。

///|

///| The ParserLike extension-point combinator set. In MoonBit, `Parser[T]` is

///| a wrapper over `(State) -> ParseResult[T]`, so any custom type that can

///| expose such a function plugs into astrolabe combinators directly: pass a

///| bare run-function to `pmap`/`pbind`/`palt`/`poption`, or expose a

///| `run_fn(self)` method on your wrapper type (see `Traced[T]` in

///| `examples/ext`). Typical scenarios: logging/counting wrappers, memoized

///| parsers, adapters for other parser libraries. Design note: MoonBit traits

///| do not support parameterization separating the implementing type from the

///| result type, so this extension point uses the functional convention —

///| the same extension point as `Parser::of`.

///| 获取 `Parser` 的运行函数 — ParserLike 扩展点的标准入口。

///|

///| Extract the run-function from a `Parser` — the standard entry to the

///| ParserLike extension point.

pub fn[T] Parser::run_fn(self : Parser[T]) -> (State) -> ParseResult[T] noraise {
  self.run
}

///| 对任意 `ParserLike` 运行函数应用变换 — 通用组合子扩展点。

///| 返回具体 `Parser[B]`;失败语义与 `map` 一致(原样传递)。

///|

///| Apply a transform to any ParserLike run-function — generic combinator

///| extension. Returns a concrete `Parser[B]`; failure semantics match `map`.

pub fn[A, B] pmap(
  run : (State) -> ParseResult[A],
  f : (A) -> B,
) -> Parser[B] noraise {
  Parser::of(fn(state) {
    match run(state) {
      Success(value, st) => Success(f(value), st)
      Failure(err) => Failure(err)
    }
  })
}

///| 对任意 `ParserLike` 运行函数做单调绑定 — 第二个解析器依赖第一个的结果。

///| 序列承诺语义与 `bind` 一致:第一解析器成功后,第二解析器的失败被承诺。

///|

///| Monadic bind over any ParserLike run-function — the second parser

///| depends on the first's result. Sequence-commit semantics match `bind`:

///| after the first parser succeeds, failures from the continuation are

///| committed.

pub fn[A, B] pbind(
  run : (State) -> ParseResult[A],
  f : (A) -> Parser[B],
) -> Parser[B] noraise {
  Parser::of(fn(state) {
    match run(state) {
      Failure(err) => Failure(err)
      Success(value, st) =>
        match (f(value).run)(st) {
          Success(v2, st2) => Success(v2, st2)
          Failure(err2) => Failure(err2.commit())
        }
    }
  })
}

///| 对任意两个 `ParserLike` 运行函数做有序选择 — 未承诺失败时回溯,

///| 两分支都失败时通过 `ParseError::merge` 聚合错误(与 `alt` 一致)。

///|

///| Ordered choice over any two ParserLike run-functions — backtracks on

///| uncommitted failure and aggregates errors via `ParseError::merge` when

///| both branches fail (same semantics as `alt`).

pub fn[A] palt(
  run1 : (State) -> ParseResult[A],
  run2 : (State) -> ParseResult[A],
) -> Parser[A] noraise {
  Parser::of(fn(state) {
    match run1(state) {
      Success(value, st) => Success(value, st)
      Failure(err) =>
        if err.committed() {
          Failure(err)
        } else {
          match run2(state) {
            Success(value, st) => Success(value, st)
            Failure(err2) => Failure(err.merge(err2))
          }
        }
    }
  })
}

///| 对任意 `ParserLike` 运行函数在未承诺失败时回退到 `default`。

///| 承诺失败仍然传播(与 `option` 语义一致)。

///|

///| Fall back to `default` when any ParserLike run-function fails

///| uncommitted. Committed failures still propagate (same semantics as

///| `option`).

pub fn[A] poption(
  run : (State) -> ParseResult[A],
  default : A,
) -> Parser[A] noraise {
  Parser::of(fn(state) {
    match run(state) {
      Success(value, st) => Success(value, st)
      Failure(err) =>
        if err.committed() {
          Failure(err)
        } else {
          Success(default, state)
        }
    }
  })
}