nicer pattern matching
This commit is contained in:
parent
d5821c9cb9
commit
794cd3f120
2 changed files with 30 additions and 0 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { compareStrings } from "../compare/primitives.js";
|
||||
import { unit } from "../primitives/unit.js";
|
||||
import { capitalizeFirstLetter } from "../util/util.js";
|
||||
|
||||
const eatParameters = (numParams, result) => {
|
||||
|
|
@ -33,6 +34,24 @@ const matchFn = (enumm, variantNames) => {
|
|||
};
|
||||
};
|
||||
|
||||
export const symbolElse = Symbol('else');
|
||||
|
||||
export const makeNiceMatchFn = (variantNames) => handlers => enumm => {
|
||||
const incomplete = variantNames.filter(({l: variant}) => !handlers.hasOwnProperty(variant)).length > 0;
|
||||
if (incomplete && !handlers.hasOwnProperty(symbolElse)) {
|
||||
throw new Error("if not every variant is handled, must have 'else' handler");
|
||||
}
|
||||
if (!incomplete && handlers.hasOwnProperty(symbolElse)) {
|
||||
console.warn("'else' handler will never be invoked because every variant is already handled");
|
||||
}
|
||||
for (const [variant, handler] of Object.entries(handlers)) {
|
||||
if (enumm.variant === variant) {
|
||||
return handler(enumm.value);
|
||||
}
|
||||
}
|
||||
return handlers[symbolElse](unit);
|
||||
}
|
||||
|
||||
export const makeConstructors = variantNames => {
|
||||
if (new Set(variantNames).size !== variantNames.length) {
|
||||
throw new Error("precondition failed: non-unique variant names");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { makeTypeConstructor } from "../lib/meta/type_constructor.js";
|
||||
import { Char, Double, Unit } from "../lib/primitives/primitive_types.js";
|
||||
import { unit } from "../lib/primitives/unit.js";
|
||||
import { makeNiceMatchFn, symbolElse } from "../lib/structures/enum.js";
|
||||
import { makeModuleEnum } from "../lib/structures/enum.types.js";
|
||||
import { newProduct } from "../lib/structures/product.js";
|
||||
import { lsType } from "../lib/structures/type_constructors.types.js";
|
||||
|
|
@ -44,3 +45,13 @@ const description = symptom => matchSymptom(symptom)
|
|||
assert.strictEqual("Fever (38.5 degrees)", description(fever));
|
||||
assert.strictEqual("Confused" , description(confused));
|
||||
assert.strictEqual("Other: sweating" , description(other));
|
||||
|
||||
// looks almost the same, but no currying, and the ability to have 'else'
|
||||
const description2 = makeNiceMatchFn(variants)({
|
||||
fever: fever => `Fever (${fever} degrees)`,
|
||||
[symbolElse]: _ => `Something else`,
|
||||
});
|
||||
|
||||
assert.strictEqual("Fever (38.5 degrees)", description2(fever));
|
||||
assert.strictEqual("Something else" , description2(confused));
|
||||
assert.strictEqual("Something else" , description2(other));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue