simplify 'struct'

This commit is contained in:
Joeri Exelmans 2025-06-02 15:28:07 +02:00
parent 43342e90d4
commit 366b1ec4e0
3 changed files with 57 additions and 52 deletions

View file

@ -1,33 +1,30 @@
import { unit } from "../primitives/unit.js";
import { capitalizeFirstLetter } from "../util/util.js";
import { newProduct, getLeft, getRight } from "./product.js";
export const makeConstructor = nParams => {
const internal = (nParams, ret) => {
if (nParams === 0) {
export const makeConstructor = fieldNames => {
const internal = (fieldNames, ret) => {
if (fieldNames.length === 0) {
const result = ret(unit);
return result;
}
return nextParam => {
const wrappedName = 'wrapped_' + ret.name;
const [fieldName, ...rest] = fieldNames;
const wrappedName = 'ctor_' + fieldName;
const newRet = {
[wrappedName]: inner => newProduct(nextParam)(ret(inner)),
[wrappedName]: inner => ({[fieldName]: nextParam, ...ret(inner)}),
}[wrappedName];
return internal(nParams-1, newRet);
return internal(rest, newRet);
}
};
const id = x => x;
return internal(nParams, id);
return internal(fieldNames, id);
};
export const makeGetters = fieldNames => {
if (fieldNames.length === 0) {
return [];
}
const [fieldName, ...rest] = fieldNames;
const getterName = `get${capitalizeFirstLetter(fieldName)}`;
return [
{ [getterName]: obj => getLeft(obj) }[getterName],
...makeGetters(rest).map(getter => ({[getter.name]: obj => getter(getRight(obj))}[getter.name])),
];
return fieldNames.map(fieldName => {
const getterName = `get${capitalizeFirstLetter(fieldName)}`;
return {
[getterName]: obj => obj[fieldName],
}[getterName];
})
};

View file

@ -1,40 +1,14 @@
import { getDefaultTypeParser } from "../parser/type_parser.js";
import { newDynamic } from "../primitives/dynamic.js";
import { Type, Unit } from "../primitives/primitive_types.js";
import { zip } from "../util/util.js";
import { map } from "./list.js";
import { getLeft, getRight } from "./product.js";
import { makeConstructor, makeGetters } from "./struct.js";
import { fnType, prodType } from "./type_constructors.types.js";
// 'fields' is an array of (name: string, type: Type) pairs.
// e.g.:
// [{l: "x", r: Double}, {l: "y", r: Double}]
// results in the type (Double × (Double × Unit))
export const structType = (fields, rootSelf) => {
// console.log("structType..", fields);
if (fields.length === 0) {
return Unit;
}
const [field, ...rest] = fields;
const fieldType = getRight(field);
return prodType
(self => {
// console.log("requested left type (of structType)")
return fieldType(rootSelf || self);
})
(self => {
// console.log("requested right type (of structType)")
return structType(rest, self);
});
};
import { fnType } from "./type_constructors.types.js";
export const makeConstructorType = type => fields => {
if (fields.length === 0) {
return type;
// return structType(fields);
}
const [field, ...rest] = fields;
const fieldType = getRight(field);
@ -42,7 +16,6 @@ export const makeConstructorType = type => fields => {
};
export const makeGettersTypes = type => fields => {
// const type = structType(fields);
return fields.map(field => {
const fieldType = getRight(field);
return fnType(_ => type)(_ => fieldType);
@ -51,14 +24,11 @@ export const makeGettersTypes = type => fields => {
export const makeModuleStruct = type => fields => {
const fieldNames = map(fields)(getLeft);
// const type = structType(fields);
const ctor = makeConstructor(fields.length);
const ctorType = makeConstructorType(fields);
const getterTypes = makeGettersTypes(fields);
const ctor = makeConstructor(fieldNames);
const ctorType = makeConstructorType(type)(fields);
const getterTypes = makeGettersTypes(type)(fields);
const getters = makeGetters(fieldNames);
const module = [
// ["type", newDynamic(type)(Type)],
// constructor
["ctor", newDynamic(ctor)(ctorType)],
@ -72,6 +42,6 @@ export const makeModuleStruct = type => fields => {
const mkType = getDefaultTypeParser();
export const ModuleStruct = [
["structType" , newDynamic(structType )(mkType("[String*Type] -> Type" ))],
// ["structType" , newDynamic(structType )(mkType("[String*Type] -> Type" ))],
["makeModuleStruct", newDynamic(makeModuleStruct)(mkType("[String*Type] -> [Dynamic]"))],
];