@jsoldi/hkt
Version:
Higher kinded types for typescript and a few utility monads.
88 lines • 3.37 kB
JavaScript
;
// import { maybe, state, TypeArg, KRoot, monadPlus, chain } from "./index.js";
// // alias for maybe
// const m = maybe;
// // put maybe inside a state monad
// const s = state.of<string>().transform(m);
// // Non-higher-kinded parser type
// type Parser<T> = TypeArg<typeof s, T>; // (a: string) => Maybe<[T, string]>
// // Higher-kinded parser type
// interface KParser extends KRoot {
// readonly 0: unknown
// readonly body: Parser<this[0]>
// }
// const parser = (() => {
// // Create a monadPlus (monad & monoid) instance for the parser
// const base = monadPlus<KParser>({
// unit: s.unit,
// bind: s.bind,
// empty: () => _ => m.empty(),
// // Append returns the first non-empty result
// append: (p1, p2) => input => m.append(p1(input), p2(input))
// });
// // Next character parser
// const next: Parser<string> = input => input.length === 0
// ? m.empty()
// : m.unit([input[0], input.slice(1)]);
// // Regex parser
// const regex = (re: RegExp): Parser<string> => (input: string) => {
// const match = input.match(re);
// return match === null
// ? m.empty()
// : m.unit([match[0], input.slice(match[0].length)]);
// }
// // Chain left-associative parser
// const chainl1 = <A>(p: Parser<A>, op: Parser<(a: A, b: A) => A>): Parser<A> =>
// base.bind(
// p,
// a => base.map(
// base.many(
// base.bind(
// op,
// f => base.map(p, b => (x: A) => f(x, b))
// )
// ),
// vs => vs.reduce((a, f) => f(a), a)
// )
// );
// // Character parser
// const char = (c: string) => base.filter<string>(s => s === c)(next);
// return { ...base, next, regex, chainl1, char }
// })();
// const math = (() => {
// // Number parser
// const num = parser.map(parser.regex(/^\d+(\.\d+)?/), parseFloat);
// // Addition and subtraction parser
// const addOp = parser.append(
// parser.map(parser.char('+'), _ => (a: number, b: number) => a + b),
// parser.map(parser.char('-'), _ => (a: number, b: number) => a - b)
// );
// // Multiplication and division parser
// const mulOp = parser.append(
// parser.map(parser.char('*'), _ => (a: number, b: number) => a * b),
// parser.map(parser.char('/'), _ => (a: number, b: number) => a / b)
// );
// // Bracketed expression parser
// const group: Parser<number> = parser.append(
// num,
// parser.pipe(
// parser.char('('),
// _ => expr,
// _ => parser.char(')'),
// (_, n) => parser.unit(n)
// )
// );
// // Arithmetic expression parser
// const expr = parser.chainl1(parser.chainl1(group, mulOp), addOp);
// // Final parser
// const parse = chain(
// (s: string) => s.replace(/\s/g, ''),
// expr,
// m.fmap(([n]) => n),
// m.else(() => 'Invalid expression')
// );
// return { ...parser, num, addOp, mulOp, group, expr, parse }
// })();
// const result = math.parse('10.1 + 20 * 30 + 40'); // 650.1
// console.log(result);
//# sourceMappingURL=parser-unsafe.js.map