simplify: no distinction between generic types and 'normal' types.
This commit is contained in:
parent
b4826605af
commit
a664ddac8a
27 changed files with 535 additions and 360 deletions
|
|
@ -11,7 +11,7 @@ const eatParameters = (numParams, result) => {
|
|||
|
||||
export const makeMatchFn = variants => {
|
||||
if (variants.length === 0) {
|
||||
return undefined;
|
||||
throw new Error("Bottom!");
|
||||
}
|
||||
const [_, ...remainingVariants] = variants;
|
||||
return sum => handler => {
|
||||
|
|
@ -34,4 +34,4 @@ export const makeConstructors = variants => {
|
|||
...makeConstructors(remainingVariants).map(ctor =>
|
||||
({[ctor.name]: val => newRight(ctor(val))}[ctor.name])),
|
||||
];
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { Bottom } from "../primitives/primitive_types.js";
|
||||
import { makeCompareFn } from "../compare/dynamic.js";
|
||||
import { makeGeneric } from "../generics/generics.js";
|
||||
import { newDynamic } from "../primitives/dynamic.js";
|
||||
import { Bottom, Type } from "../primitives/primitive_types.js";
|
||||
import { makeConstructors, makeMatchFn } from "./enum.js";
|
||||
import { getRight } from "./product.js";
|
||||
import { sumType } from "./type_constructors.js";
|
||||
import { fnType, sumType } from "./type_constructors.js";
|
||||
|
||||
// 'variants' is an array of (name: string, type: Type) pairs.
|
||||
// e.g., the list of variants:
|
||||
|
|
@ -10,11 +14,67 @@ import { sumType } from "./type_constructors.js";
|
|||
// results in the type:
|
||||
// (Int | ([Int] | (Unit | ⊥)))
|
||||
|
||||
export const enumType = variants => {
|
||||
const _enumType = rootSelf => variants => {
|
||||
// console.log("enumType..", variants);
|
||||
if (variants.length === 0) {
|
||||
return Bottom; // empty enum is equal to Bottom-type (cannot be instantiated)
|
||||
}
|
||||
const [variant, ...rest] = variants;
|
||||
const variantType = getRight(variant);
|
||||
return sumType(() => variantType)(() => enumType(rest));
|
||||
return sumType
|
||||
(self => {
|
||||
// console.log("requested left type (of enumType)")
|
||||
return variantType(rootSelf || self);
|
||||
})
|
||||
(self => {
|
||||
// console.log("requested right type (of enumType)")
|
||||
return _enumType(self)(rest)
|
||||
});
|
||||
};
|
||||
|
||||
export const enumType = _enumType(null);
|
||||
|
||||
export const makeConstructorTypes = type => variants => {
|
||||
return variants.map(variant => {
|
||||
const variantType = getRight(variant);
|
||||
return fnType(_ => variantType)(_ => type);
|
||||
});
|
||||
}
|
||||
|
||||
export const makeMatchFnType = type => variants => {
|
||||
return makeGeneric(resultType =>
|
||||
fnType
|
||||
(_ => type)
|
||||
(_ => handlerType(resultType)(type)(variants)));
|
||||
}
|
||||
|
||||
const handlerType = resultType => type => variants => {
|
||||
if (variants.length === 0) {
|
||||
return resultType;
|
||||
}
|
||||
const [variant, ...rest] = variants;
|
||||
const variantType = getRight(variant);
|
||||
return fnType
|
||||
(_ => fnType(_ => variantType)(_ => resultType)), // handler
|
||||
(_ => handlerType(resultType)(type)(rest)); // rest
|
||||
}
|
||||
|
||||
export const makeModuleEnum = type => variants => {
|
||||
const ctors = makeConstructors(variants);
|
||||
const ctorTypes = makeConstructorTypes(type)(variants);
|
||||
const matchFn = makeMatchFn(variants);
|
||||
const matchFnType = makeMatchFnType(type)(variants);
|
||||
const module = [
|
||||
// newDynamic(type)(Type),
|
||||
|
||||
// constructors:
|
||||
...zip(ctors, ctorTypes)
|
||||
.map(([ctor, ctorType]) => newDynamic(ctor)(ctorType)),
|
||||
|
||||
// match-function:
|
||||
newDynamic(matchFn, matchFnType),
|
||||
|
||||
// compare-function:
|
||||
newDynamic(makeCompareFn(enumType(variants)))
|
||||
];
|
||||
}
|
||||
|
|
@ -11,6 +11,15 @@ export const add = set => key => set.tree.get(key) === true ? set : new RBTreeWr
|
|||
export const remove = set => key => new RBTreeWrapper(set.tree.remove(key));
|
||||
export const length = set => set.tree.length;
|
||||
|
||||
export const fold = set => callback => initial => {
|
||||
let acc = initial;
|
||||
let iter = set.tree.begin;
|
||||
while (iter !== undefined && iter.valid) {
|
||||
acc = callback(acc, iter.key);
|
||||
}
|
||||
return acc;
|
||||
};
|
||||
|
||||
export const first = set => set.tree.begin;
|
||||
export const last = set => set.tree.end;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { makeTypeParser } from "../parser/type_parser.js";
|
||||
import { makeTypeConstructor } from "../meta/type_constructor.js";
|
||||
import { emptySet, has, add, remove, length, first, read, last } from "./set.js";
|
||||
import { emptySet, has, add, remove, length, first, read, last, fold } from "./set.js";
|
||||
|
||||
const setIterator = makeTypeConstructor('SetIterator__f6b0ddd78ed41c58e5a442f2681da011')(1);
|
||||
|
||||
|
|
@ -14,6 +14,7 @@ export const ModuleSet = [
|
|||
{ i: add , t: mkType("∀a: {a} -> a -> {a}")},
|
||||
{ i: remove , t: mkType("∀a: {a} -> a -> {a}")},
|
||||
{ i: length , t: mkType("∀a: {a} -> Int")},
|
||||
{ i: fold , t: mkType("∀a,b: {a} -> (b -> a -> b) -> b")},
|
||||
{ i: first , t: mkType("∀a: {a} -> <a>")},
|
||||
{ i: last , t: mkType("∀a: {a} -> <a>")},
|
||||
{ i: read , t: mkType("∀a: <a> -> (Unit + (a * <a>))")},
|
||||
|
|
|
|||
|
|
@ -13,40 +13,56 @@ import { fnType, prodType } from "./type_constructors.js";
|
|||
// [{l: "x", r: Double}, {l: "y", r: Double}]
|
||||
// results in the type (Double × (Double × Unit))
|
||||
|
||||
export const structType = fieldTypes => {
|
||||
if (fieldTypes.length === 0) {
|
||||
export const structType = (fields, rootSelf) => {
|
||||
// console.log("structType..", fields);
|
||||
if (fields.length === 0) {
|
||||
return Unit;
|
||||
}
|
||||
const [fieldType, ...rest] = fieldTypes;
|
||||
return prodType(_ => fieldType)(_ => structType(rest));
|
||||
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);
|
||||
});
|
||||
};
|
||||
|
||||
export const makeConstructorType = fieldTypes => {
|
||||
if (fieldTypes.length === 0) {
|
||||
return structType(fieldTypes);
|
||||
export const makeConstructorType = type => fields => {
|
||||
if (fields.length === 0) {
|
||||
return type;
|
||||
// return structType(fields);
|
||||
}
|
||||
const [fieldType, ...rest] = fieldTypes;
|
||||
return fnType(_ => fieldType)(_ => makeConstructorType(rest));
|
||||
const [field, ...rest] = fields;
|
||||
const fieldType = getRight(field);
|
||||
return fnType(_ => fieldType)(_ => makeConstructorType(type, rest));
|
||||
};
|
||||
|
||||
export const makeGettersTypes = fieldTypes => {
|
||||
const type = structType(fieldTypes);
|
||||
return fieldTypes.map(fieldType => {
|
||||
export const makeGettersTypes = type => fields => {
|
||||
// const type = structType(fields);
|
||||
return fields.map(field => {
|
||||
const fieldType = getRight(field);
|
||||
return fnType(_ => type)(_ => fieldType);
|
||||
});
|
||||
};
|
||||
|
||||
export const makeModuleStruct = fields => {
|
||||
export const makeModuleStruct = type => fields => {
|
||||
const fieldNames = map(fields)(getLeft);
|
||||
const fieldTypes = map(fields)(getRight);
|
||||
const type = structType(fieldTypes);
|
||||
// const type = structType(fields);
|
||||
const ctor = makeConstructor(fields.length);
|
||||
const ctorType = makeConstructorType(fieldTypes);
|
||||
const getterTypes = makeGettersTypes(fieldTypes);
|
||||
const ctorType = makeConstructorType(fields);
|
||||
const getterTypes = makeGettersTypes(fields);
|
||||
const getters = makeGetters(fieldNames);
|
||||
const module = [
|
||||
{i: type, t: Type},
|
||||
// {i: type, t: Type},
|
||||
|
||||
// constructor
|
||||
{i: ctor, t: ctorType},
|
||||
|
||||
// getters:
|
||||
...zip(getters, getterTypes)
|
||||
.map(([getter, getterType]) => newDynamic(getter)(getterType)),
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
import { getDefaultTypeParser } from "../parser/type_parser.js";
|
||||
import { SymbolT } from "../primitives/primitive_types.js";
|
||||
import { UUID } from "../primitives/primitive_types.js";
|
||||
import { dictType, fnType, lsType, prodType, setType, sumType, symbolDict, symbolFunction, symbolList, symbolProduct, symbolSet, symbolSum } from "./type_constructors.js";
|
||||
|
||||
const mkType = getDefaultTypeParser();
|
||||
|
||||
export const ModuleStructuralSymbols = [
|
||||
{ i: symbolSet , t: SymbolT },
|
||||
{ i: symbolList , t: SymbolT },
|
||||
{ i: symbolProduct , t: SymbolT },
|
||||
{ i: symbolSum , t: SymbolT },
|
||||
{ i: symbolDict , t: SymbolT },
|
||||
{ i: symbolFunction , t: SymbolT },
|
||||
{ i: symbolSet , t: UUID },
|
||||
{ i: symbolList , t: UUID },
|
||||
{ i: symbolProduct , t: UUID },
|
||||
{ i: symbolSum , t: UUID },
|
||||
{ i: symbolDict , t: UUID },
|
||||
{ i: symbolFunction , t: UUID },
|
||||
];
|
||||
|
||||
export const ModuleTypeConstructors = [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue