simplify 'struct'
This commit is contained in:
parent
43342e90d4
commit
366b1ec4e0
3 changed files with 57 additions and 52 deletions
|
|
@ -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];
|
||||
})
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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]"))],
|
||||
];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue