sure, here’s some from one of my rescript code bases:
...
/**
Parses three parsers in sequence, returning a triple of their results.
All must succeed.
*/
let seq3 = (p1, p2, p3): parser<_> => {
st => {
let? Ok((v1, st1)) = p1(st)
let? Ok((v2, st2)) = p2(st1)
let? Ok((v3, st3)) = p3(st2)
Ok(((v1, v2, v3), st3))
}
}
/**
Parses four parsers in sequence, returning a quadruple of their results.
All must succeed.
*/
let seq4 = (p1, p2, p3, p4): parser<_> => {
st => {
let? Ok((v1, st1)) = p1(st)
let? Ok((v2, st2)) = p2(st1)
let? Ok((v3, st3)) = p3(st2)
let? Ok((v4, st4)) = p4(st3)
Ok(((v1, v2, v3, v4), st4))
}
}
...
it’s from our small in-house rolled parser combinator lib
from the same project in a different place:
...
// ── Lexing ──
let? Ok(toks) = switch lexer->DSL_Compilation_Lexer.tokenize(src) {
| Ok(r) => Ok(r)
| Error({span, msg}) => Error(CompilationError.UnknownToken({span, msg}))
}
// ── Parsing ──
let? Ok(ast) = switch parser.parseAll(toks) {
| Ok(r) => Ok(r)
| Error({kind: UnexpectedToken, span, msg}) =>
Error(CompilationError.UnexpectedToken({span, msg}))
}
...