UNPKG

@jsoldi/hkt

Version:

Higher kinded types for typescript and a few utility monads.

88 lines 3.37 kB
"use strict"; // 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