Skip to content

Instantly share code, notes, and snippets.

const between = (l, p, r) => sequence([l, p, r]).map(v => v[1])
const not = parser =>
new Parser(stream =>
parser.run(stream)
.fold(
(value, s) => new Failure('not failed', stream),
(value, s) =>
stream.length > 0
? new Success(stream.head(), stream.move(1))
: new Failure('unexpected end', stream)))
const string = str => sequence(str.split('').map(char))
const zeroOrMore = parser =>
new Parser(stream =>
parser.run(stream)
.fold(
(value, s) => zeroOrMore(parser).map(rest => [value].concat(rest)).run(s),
(value, s) => new Success([], stream)))
const lookahead = parser =>
new Parser(stream =>
parser.run(stream)
.fold(
(v) => new Success(v, stream),
(v) => new Failure(v, stream)))
const maybe = parser =>
new Parser(stream =>
parser.run(stream)
.fold(
(v, s) => new Success(v, s),
(v, s) => new Success(null, stream)))
const always = value =>
new Parser(stream => new Success(value, stream))
const never = value =>
new Parser(stream => new Failure(value, stream))
const append = (p1, p2) =>
p1.chain(vs => p2.map(v => vs.concat([v])))
const concat = (p1, p2) =>
const either = list =>
new Parser(stream => {
for (let i = 0; i < list.length; i++) {
const parser = list[i]
const result = parser.run(stream)
if (result instanceof Success) {
return result
}
}
return new Failure('either failed', stream)
char('a')
.chain(v1 =>
char('b')
.chain(v2 =>
char('c')
.map(v3 => [v1, v2, v3])
)
)
.run('abc')
.fold(
char('a')
.chain(v => char('b'))
.chain(v => char('c'))
.run('abc')
.fold(
v => console.log('success', v)
e => console.log('error', e)
)
// => success c