37 lines
1.1 KiB
JavaScript
37 lines
1.1 KiB
JavaScript
import { capitalizeFirstLetter } from "../util/util.js";
|
|
import { newProduct as newProduct, getLeft } from "./product.js";
|
|
import { newLeft, newRight, match } from "./sum.js";
|
|
|
|
const eatParameters = (numParams, result) => {
|
|
if (numParams === 0) {
|
|
return result;
|
|
}
|
|
else return () => eatParameters(numParams-1, result);
|
|
}
|
|
|
|
export const makeMatchFn = variants => {
|
|
if (variants.length === 0) {
|
|
throw new Error("Bottom!");
|
|
}
|
|
const [_, ...remainingVariants] = variants;
|
|
return sum => handler => {
|
|
return match(sum)
|
|
(leftValue => eatParameters(remainingVariants.length, handler(leftValue)))
|
|
(rightValue => makeMatchFn(remainingVariants)(rightValue));
|
|
};
|
|
};
|
|
|
|
export const makeConstructors = variants => {
|
|
if (variants.length === 0) {
|
|
return [];
|
|
}
|
|
const [variant, ...remainingVariants] = variants;
|
|
const name = getLeft(variant);
|
|
const ctorName = `new${capitalizeFirstLetter(name)}`;
|
|
const constructor = { [ctorName]: val => newLeft(val) }[ctorName];
|
|
return [
|
|
constructor,
|
|
...makeConstructors(remainingVariants).map(ctor =>
|
|
({[ctor.name]: val => newRight(ctor(val))}[ctor.name])),
|
|
];
|
|
};
|