Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
import { some } from 'fp-ts/lib/Option'
import { pipe } from 'fp-ts/lib/pipeable'
import { run } from 'parser-ts/lib/code-frame'
const isDigit = (c: string): boolean => '0123456789'.indexOf(c) !== -1
const isPunctuation = (c: string): boolean => '| =\n():,{};[]->'.indexOf(c) !== -1
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)
)
}
</a>
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 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(() =>
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]
default:
return M.tuple(types)
}
})
)
)
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,
P.apSecond(P.sepBy(S.spaces, parameterDeclaration)),
P.apFirst(equal),
P.chain(typeParameters =>
pipe(
P.sepBy1(pipeParser, constructor),
return M.tuple(types)
}
})
)
),
P.apFirst(rightParens)
),
'a tuple'
)
const arrow = S.fold([S.spaces, S.string('->'), S.spaces])
/**
* @since 0.4.0
*/
export const fun: P.Parser = P.expected(
pipe(
S.spaces,
P.chain(() =>
pipe(
ref,
P.alt(() => tuple),
P.chain(domain =>
pipe(
arrow,
P.apSecond(type),
P.map(codomain => M.fun(domain, codomain))
)
)
)
)
),