dope2/structures/types.js
Joeri Exelmans 8eec5b9239 recursive types (and operations on them, like pretty-printing, comparison and unification) seem to be working.
big part of the code base still needs to be 'ported' to the updated type constructors.
2025-05-05 17:17:45 +02:00

54 lines
1.9 KiB
JavaScript

// to break up dependency cycles, type constructors are defined in their own JS module
import { Type } from "../primitives/types.js";
import { getSymbol, makeTypeConstructor } from "../type_constructor.js";
// Function type
// The registry ensures that we never accidentally create more than one JS object for the same function type.
// It is a cheap workaround for JS lacking customizable hash-functions and equality-testing-functions.
// This same pattern is repeated throughout the code for all non-nullary type constructors (list, sum, product, ...)
export const symbolFunction = Symbol('Function');
export const fnType = makeTypeConstructor(symbolFunction)(2);
export const isFunction = type => getSymbol(type) === symbolFunction;
// Convenience function. Creates a function type, and also create Type-links for the function type (being typed by Function) and for all the nested function types. Saves a lot of code writing.
export const typedFnType = (instance, callback, typeOfType = Type) => {
const fnTs = [];
const wrappedFnType = inType => outType => {
const fnT = fnType(() => inType)(() => outType);
fnTs.push(fnT);
return fnT;
};
const t = callback(wrappedFnType); // force evaluation
if (t.typeVars && typeOfType === Type) {
throw new Error("you probably meant to create a GenericType");
}
const res = [
{ i: instance, t },
{ i: t , t: typeOfType },
// ...fnTs.map(fnT => ({ i: fnT, t: Type })),
];
return res;
};
// Sum type
export const symbolSum = Symbol("Sum");
export const sumType = makeTypeConstructor(symbolSum)(2);
// Product type
export const symbolProduct = Symbol("Product");
export const prodType = makeTypeConstructor(symbolProduct)(2);
// List type
export const symbolList = Symbol('List');
export const lsType = makeTypeConstructor(symbolList)(1);
// Set type
export const symbolSet = Symbol('Set');
export const setType = makeTypeConstructor(symbolSet)(1);