UNPKG

ts-union

Version:

ADT (sum type) in typescript inspired by ML language family

124 lines (93 loc) 2.87 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const of = val => val; 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; exports.Union = Union; exports.of = of; //# sourceMappingURL=index.js.map