ts-union
Version:
ADT (sum type) in typescript inspired by ML language family
87 lines • 8.19 kB
JavaScript
export const of = ((val) => val);
export const Union = (recOrFunc) => {
const record = typeof recOrFunc === 'function' ? recOrFunc(undefined) : recOrFunc;
// tslint:disable-next-line:prefer-object-spread
return Object.assign({
if: createUnpack(record),
match: (a, b) => (b ? evalMatch(a, b) : (val) => evalMatch(val, a)),
matchWith: (_other, // yep, it is only used to "remember" type
matchObj) => createMatchTupleFunction(matchObj),
}, createConstructors(record, typeof recOrFunc === 'function'));
};
const createMatchTupleFunction = (matchObj) => {
const { default: def } = matchObj;
return function matchTuple(a, b) {
const { p0: valA, k: keyA } = a;
const { p0: valB, k: KeyB } = b;
if (keyA in matchObj) {
const inner = matchObj[keyA];
if (inner !== undefined && KeyB in inner) {
const matchedFunction = inner[KeyB];
if (matchedFunction !== undefined) {
return matchedFunction(valA, valB);
}
}
}
return def(a, b);
};
};
const evalMatch = (val, cases) => {
// first elem is always the key
const handler = cases[getKey(val)];
return handler ? invoke(val, handler) : cases.default && cases.default(val);
};
const createConstructors = (rec, isGeneric) => {
const result = {};
// tslint:disable-next-line: forin
for (const key in rec) {
result[key] = createCtor(key, rec, isGeneric);
}
return result;
};
const createCtor = (key, rec, isGeneric) => {
const val = rec[key];
// it means that it was constructed with of(null)
if (val === null) {
const frozenVal = Object.freeze(makeValue(key, undefined, undefined, undefined));
return isGeneric ? () => frozenVal : frozenVal;
}
// tslint:disable-next-line:no-if-statement
if (val !== undefined) {
const res = makeValue(key, val, undefined, undefined);
return (() => res);
}
return ((p0, p1, p2) => makeValue(key, p0, p1, p2));
};
const createUnpack = (rec) => {
const result = {};
// tslint:disable-next-line:forin
for (const key in rec) {
result[key] = createUnpackFunc(key);
}
return result;
};
const createUnpackFunc = (key) => ((val, f, els) => getKey(val) === key ? invoke(val, f) : els && els(val));
const makeValue = (k, p0, p1, p2) => ({
k,
p0,
p1,
p2,
a: arity(p0, p1, p2),
});
const invoke = (val, f) => {
switch (val.a) {
case 0:
return f();
case 1:
return f(val.p0);
case 2:
return f(val.p0, val.p1);
case 3:
return f(val.p0, val.p1, val.p2);
}
};
const getKey = (val) => val.k;
// const getParams = (val: any) => val.p;
const arity = (p0, p1, p2) => p2 !== undefined ? 3 : p1 !== undefined ? 2 : p0 !== undefined ? 1 : 0;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBa0RBLE1BQU0sQ0FBQyxNQUFNLEVBQUUsR0FBVSxDQUFDLENBQUMsR0FBUSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQVEsQ0FBQztBQThOcEQsTUFBTSxDQUFDLE1BQU0sS0FBSyxHQUFjLENBQzlCLFNBQWtDLEVBQ2xDLEVBQUU7SUFDRixNQUFNLE1BQU0sR0FDVixPQUFPLFNBQVMsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBRSxTQUFnQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUU3RixnREFBZ0Q7SUFDaEQsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUNsQjtRQUNFLEVBQUUsRUFBRSxZQUFZLENBQUMsTUFBTSxDQUFDO1FBQ3hCLEtBQUssRUFBRSxDQUFDLENBQU0sRUFBRSxDQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNuRixTQUFTLEVBQUUsQ0FDVCxNQUF3QixFQUFFLDBDQUEwQztRQUNwRSxRQUE0QyxFQUM1QyxFQUFFLENBQUMsd0JBQXdCLENBQUMsUUFBUSxDQUFDO0tBQ3hDLEVBQ0Qsa0JBQWtCLENBQUMsTUFBTSxFQUFFLE9BQU8sU0FBUyxLQUFLLFVBQVUsQ0FBQyxDQUNyRCxDQUFDO0FBQ1gsQ0FBQyxDQUFDO0FBRUYsTUFBTSx3QkFBd0IsR0FBRyxDQUsvQixRQUF3QyxFQUN4QyxFQUFFO0lBQ0YsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxRQUFRLENBQUM7SUFDbEMsT0FBTyxTQUFTLFVBQVUsQ0FBQyxDQUFjLEVBQUUs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