44 lines
1.1 KiB
JavaScript
44 lines
1.1 KiB
JavaScript
import { capitalizeFirstLetter } from "../util/util.js";
|
|
|
|
const eatParameters = (numParams, result) => {
|
|
if (numParams === 0) {
|
|
return result;
|
|
}
|
|
else return () => eatParameters(numParams-1, result);
|
|
}
|
|
|
|
export const makeMatchFn = variantNames => {
|
|
if (variantNames.length === 0) {
|
|
return _ => {
|
|
throw new Error("Bottom!");
|
|
};
|
|
}
|
|
return enumm => {
|
|
return matchFn(enumm, variantNames);
|
|
}
|
|
};
|
|
|
|
const matchFn = (enumm, variantNames) => {
|
|
const [variantName, ...remaining] = variantNames;
|
|
return handler => {
|
|
if (enumm.variant === variantName) {
|
|
return eatParameters(
|
|
remaining.length,
|
|
handler(enumm.value));
|
|
}
|
|
else {
|
|
return matchFn(enumm, remaining);
|
|
}
|
|
};
|
|
};
|
|
|
|
export const makeConstructors = variantNames => {
|
|
if (new Set(variantNames).size !== variantNames.length) {
|
|
throw new Error("precondition failed: non-unique variant names");
|
|
}
|
|
return variantNames.map(variantName => {
|
|
const ctorName = `new${capitalizeFirstLetter(variantName)}`;
|
|
const ctor = { [ctorName]: value => ({variant: variantName, value}) }[ctorName];
|
|
return ctor;
|
|
})
|
|
};
|