branching and very basic merging of slots

This commit is contained in:
Joeri Exelmans 2025-04-17 09:19:41 +02:00
parent 614e6c0fdb
commit 3978f7f835
32 changed files with 684 additions and 420 deletions

65
structures/struct.js Normal file
View file

@ -0,0 +1,65 @@
import { Unit } from "../primitives/types.js";
import { unit } from "../primitives/unit.js";
import { constructorProduct, getLeft, getRight } from "./product.js";
import { fnType, prodType } from "./types.js";
function capitalizeFirstLetter(val) {
return String(val).charAt(0).toUpperCase() + String(val).slice(1);
}
// [{l: "x", r: Double}, {l: "y", r: Double}] => (Double × (Double × Unit))
export const structType = fields => {
if (fields.length === 0) {
return Unit;
}
const [field, ...rest] = fields;
const fieldType = getRight(field);
return prodType(fieldType)(structType(rest));
};
export const makeConstructor = fields => {
const internal = (nParams, ret) => {
if (nParams === 0) {
const result = ret(unit);
return result;
}
return nextParam => {
const wrappedName = 'wrapped_' + ret.name;
const newRet = {
[wrappedName]: inner => constructorProduct(nextParam)(ret(inner)),
}[wrappedName];
return internal(nParams-1, newRet);
}
};
const id = x => x;
return internal(fields.length, id);
};
export const makeConstructorType = type => fields => {
if (fields.length === 0) {
return type;
}
const [field, ...rest] = fields;
const fieldType = getRight(field);
return fnType(fieldType)(makeConstructorType(rest));
};
export const makeGetters = fields => {
if (fields.length === 0) {
return [];
}
const [field, ...rest] = fields;
const fieldName = getLeft(field);
const getterName = `get${capitalizeFirstLetter(fieldName)}`;
return [
{ [getterName]: obj => getLeft(obj) }[getterName],
...makeGetters(rest).map(getter => ({[getter.name]: obj => getter(getRight(obj))}[getter.name])),
];
};
export const makeGettersTypes = type => fields => {
return fields.map(field => {
const fieldType = getRight(field);
return fnType(type)(fieldType);
});
};