I am currently developing a parser combinator library and I am in need of creating a map
function that can take N
parsers in a tuple, along with a function that operates on those N
arguments and returns a parser that parses into the return type specified by the function.
<A, B, Z>(ps: [a: Parser<A>, b: Parser<B>], f: (a: A, b: B) => Z): Parser<Z>
<A, B, C, Z>(ps: [a: Parser<A>, b: Parser<B>, c: Parser<C>], f: (a: A, b: B, c: C) => Z): Parser<Z>
// etc
I am exploring ways to define the type of the map
function so it can handle any number of parsers.
An implementation of this function is already in place, except for defining the specific types.
To experiment with this concept, here's a minimal reproduction:
type Parser<T> = () => T;
const string: Parser<string> = null as any;
const number: Parser<number> = null as any;
type MapN = {
<A, B, Z>(ps: [a: Parser<A>, b: Parser<B>], f: (a: A, b: B) => Z): Parser<Z>,
<A, B, C, Z>(ps: [a: Parser<A>, b: Parser<B>, c: Parser<C>], f: (a: A, b: B, c: C) => Z): Parser<Z>,
}
const mapN: MapN = null as any;
const p1 = mapN([string, number], (a, b) => [a, b] as const);
const p2 = mapN([string, number, number], (a, b, c) => [a, b, c] as const);
// const p3 = mapN([string, number, string, string], (a, b, c, d) => [a, b, c, d] as const);
// const p4 = mapN([string, number, string, number, number], (a, b, c, d, e) => [a, b, c, d, e] as const);
Is there a way to define this function to work with any number of arguments while maintaining type safety?