Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const identifierFirstLetter = P.sat(c => !isDigit(c) && !isPunctuation(c))
const identifierBody = P.sat(c => !isPunctuation(c))
/**
* @since 0.4.0
*/
export const identifier: P.Parser = P.expected(
S.fold([identifierFirstLetter, C.many(identifierBody)]),
'an identifier'
)
const leftParens: P.Parser = S.fold([C.char('('), S.spaces])
const rightParens: P.Parser = S.fold([S.spaces, C.char(')')])
const withParens = <a>(parser: P.Parser): P.Parser => {
return pipe(
leftParens,
P.apSecond(parser),
P.apFirst(rightParens)
)
}
const unparametrizedRef: P.Parser = pipe(
identifier,
P.map(name => M.ref(name))
)
/**
* @since 0.4.0</a>
P.map(types => M.constructor(name, types.map(type => M.member(type))))
)
)
)
)
)
/**
* @since 0.4.0
*/
export const constructor: P.Parser = pipe(
recordConstructor,
P.alt(() => positionalConstructor)
)
const equal = S.fold([S.spaces, C.char('='), S.spaces])
const unconstrainedParameterDeclaration: P.Parser = pipe(
identifier,
P.map(name => M.parameterDeclaration(name))
)
const constrainedParameterDeclaration: P.Parser = pipe(
S.fold([C.char('('), S.spaces]),
P.apSecond(
pipe(
pair,
P.map(({ name, type }) => M.parameterDeclaration(name, some(type))),
P.apFirst(S.fold([S.spaces, C.char(')')]))
)
)
)
export const ref: P.Parser = pipe(
identifier,
P.chain(name =>
pipe(
S.spaces,
P.apSecond(
pipe(
types,
P.map(parameters => M.ref(name, parameters))
)
)
)
)
)
const comma = S.fold([S.spaces, C.char(','), S.spaces])
/**
* @since 0.4.0
*/
export const tuple: P.Parser = P.expected(
pipe(
leftParens,
P.chain(() =>
pipe(
P.sepBy(comma, type),
P.map(types => {
switch (types.length) {
case 0:
return M.unit
case 1:
return types[0]
pair,
P.map(({ name, type }) => M.parameterDeclaration(name, some(type))),
P.apFirst(S.fold([S.spaces, C.char(')')]))
)
)
)
export const parameterDeclaration = P.expected(
pipe(
unconstrainedParameterDeclaration,
P.alt(() => constrainedParameterDeclaration)
),
'a parameter'
)
const pipeParser = S.fold([S.spaces, C.char('|'), S.spaces])
/**
* @since 0.4.0
*/
export const data: P.Parser = P.expected(
pipe(
S.string('data'),
P.chain(() =>
pipe(
S.spaces,
P.apSecond(
pipe(
identifier,
P.chain(name =>
pipe(
S.spaces,
)
)
const pair: P.Parser = pipe(
identifier,
P.chain(name =>
pipe(
S.fold([S.spaces, S.string('::'), S.spaces]),
P.apSecond(type),
P.map(type => ({ name, type }))
)
)
)
const pairs: P.Parser> = pipe(
S.fold([C.char('{'), S.spaces]),
P.apSecond(P.sepBy(comma, pair)),
P.apFirst(S.fold([S.spaces, C.char('}')]))
)
const recordConstructor: P.Parser = pipe(
identifier,
P.chain(name =>
pipe(
S.spaces,
P.apSecond(
pipe(
pairs,
P.map(pairs => M.constructor(name, pairs.map(({ name, type }) => M.member(type, some(name)))))
)
)
)
const pair: P.Parser = pipe(
identifier,
P.chain(name =>
pipe(
S.fold([S.spaces, S.string('::'), S.spaces]),
P.apSecond(type),
P.map(type => ({ name, type }))
)
)
)
const pairs: P.Parser> = pipe(
S.fold([C.char('{'), S.spaces]),
P.apSecond(P.sepBy(comma, pair)),
P.apFirst(S.fold([S.spaces, C.char('}')]))
)
const recordConstructor: P.Parser = pipe(
identifier,
P.chain(name =>
pipe(
S.spaces,
P.apSecond(
pipe(
pairs,
P.map(pairs => M.constructor(name, pairs.map(({ name, type }) => M.member(type, some(name)))))
)
)
)
)
)