@unsplash/sum-types
Version:
Safe, ergonomic, non-generic sum types in TypeScript.
72 lines (71 loc) • 2.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.is = exports.deserialize = exports.serialize = exports.create = exports._ = exports.mkConstructor = void 0;
const tagKey = "_tag";
const valueKey = "_value";
const mkConstructor = () => (k) => v => ({
[tagKey]: k,
[valueKey]: v,
});
exports.mkConstructor = mkConstructor;
const mkConstructors = () => {
const xs = new Map();
return new Proxy({}, {
get: (__, tag) => {
const f = xs.get(tag);
if (f !== undefined)
return f;
const g = (0, exports.mkConstructor)()(tag);
xs.set(tag, g);
return g;
},
});
};
exports._ = Symbol("@unsplash/sum-types pattern matching wildcard");
const mkMatchW = () => (fs) => (x) => {
const tag = x[tagKey];
const g = fs[tag];
if (g !== undefined)
return g(x[valueKey]);
const h = fs[exports._];
if (h !== undefined)
return h();
throw new Error(`Failed to pattern match against tag "${tag}".`);
};
const mkMatchXW = () => (fs) => (x) => {
const tag = x[tagKey];
if (Object.prototype.hasOwnProperty.call(fs, tag))
return fs[tag];
if (Object.prototype.hasOwnProperty.call(fs, exports._))
return fs[exports._];
throw new Error(`Failed to pattern match against tag "${tag}".`);
};
const mkMatch = () => (fs) => (x) => mkMatchW()(fs)(x);
const mkMatchX = () => (fs) => (x) => mkMatchXW()(fs)(x);
const create = () => ({
mk: mkConstructors(),
match: mkMatch(),
matchW: mkMatchW(),
matchX: mkMatchX(),
matchXW: mkMatchXW(),
});
exports.create = create;
const serialize = (x) => [x[tagKey], x[valueKey]];
exports.serialize = serialize;
const deserialize = (x) => (y) => {
const k = y[0];
const v = y[1];
return x.mk[k](v);
};
exports.deserialize = deserialize;
const is = () => (k) => (f) => (x) => {
if (x === null || !["object", "function"].includes(typeof x))
return false;
const xx = x;
if (!(tagKey in xx) || xx[tagKey] !== k)
return false;
if (!(valueKey in xx) || !f(xx[valueKey]))
return false;
return true;
};
exports.is = is;