reorganize directory and file structure
This commit is contained in:
parent
1d826ea8d4
commit
48390b8556
99 changed files with 1155 additions and 1629 deletions
|
|
@ -1,13 +1,15 @@
|
|||
import { makeCompareFn } from "../compare/registry.js";
|
||||
import { Int, Unit } from "../primitives/types.js";
|
||||
import { unit } from "../primitives/unit.js";
|
||||
import { enumType, makeConstructors, makeMatchFn } from "../structures/enum.js";
|
||||
import { newProduct } from "../structures/product.js";
|
||||
import { lsType, prettyT } from "../structures/types.js";
|
||||
import { makeCompareFn } from "../lib/compare/registry.js";
|
||||
import { Int, Unit } from "../lib/primitives/primitive_types.js";
|
||||
import { unit } from "../lib/primitives/unit.js";
|
||||
import { makeConstructors, makeMatchFn } from "../lib/structures/enum.js";
|
||||
import { enumType } from "../lib/structures/enum.types.js";
|
||||
import { newProduct } from "../lib/structures/product.js";
|
||||
import { lsType } from "../lib/structures/type_constructors.js";
|
||||
import { prettyT } from "../lib/util/pretty.js";
|
||||
|
||||
const variants = [
|
||||
newProduct("price")(Int),
|
||||
newProduct("prices")(lsType(() =>Int)),
|
||||
newProduct("prices")(lsType(_ => Int)),
|
||||
newProduct("not_found")(Unit),
|
||||
];
|
||||
|
||||
|
|
@ -19,7 +21,7 @@ console.log(" ", prettyT(myEnumType));
|
|||
const [newPrice, newPrices, newNotFound] = makeConstructors(variants);
|
||||
|
||||
const price = newPrice(10);
|
||||
const prices = newPrices({ l: [20, 30] });
|
||||
const prices = newPrices([20, 30]);
|
||||
const notFound = newNotFound(unit);
|
||||
|
||||
console.log("observe the encoding of different variant instances:");
|
||||
|
|
@ -29,7 +31,7 @@ console.log(" ", notFound);
|
|||
|
||||
const myEnumToString = x => makeMatchFn(variants)(x)
|
||||
(price => `Price: ${price}`)
|
||||
(prices => `Prices: ${prices.l}`)
|
||||
(prices => `Prices: ${prices}`)
|
||||
(() => "Not found!");
|
||||
|
||||
console.log("observe the generated match function in action:");
|
||||
|
|
@ -40,9 +42,9 @@ console.log(" ", myEnumToString(notFound));
|
|||
const compareMyEnum = makeCompareFn(myEnumType);
|
||||
|
||||
console.log("observe the generated compare function in action:");
|
||||
console.log(" smaller ->", compareMyEnum(price)(prices));
|
||||
console.log(" bigger ->", compareMyEnum(prices)(price));
|
||||
console.log(" bigger ->", compareMyEnum(notFound)(price));
|
||||
console.log(" equal ->", compareMyEnum(prices)(prices));
|
||||
console.log(" smaller ->", compareMyEnum(newPrice(5))(newPrice(6)));
|
||||
console.log(" bigger ->", compareMyEnum(newPrices({ l: [5, 6] }))(newPrices({ l: [5, 5] })));
|
||||
console.log(" should be smaller ->", compareMyEnum(price)(prices));
|
||||
console.log(" should be bigger ->", compareMyEnum(prices)(price));
|
||||
console.log(" should be bigger ->", compareMyEnum(notFound)(price));
|
||||
console.log(" should be equal ->", compareMyEnum(prices)(prices));
|
||||
console.log(" should be smaller ->", compareMyEnum(newPrice(5))(newPrice(6)));
|
||||
console.log(" should be bigger ->", compareMyEnum(newPrices([5, 6]))(newPrices([5, 5])));
|
||||
|
|
|
|||
|
|
@ -1,45 +1,37 @@
|
|||
import { Bool, Int } from "../primitives/types.js";
|
||||
import { fnType, lsType } from "../structures/types.js";
|
||||
import { assign, makeGeneric, unify } from "../generics/generics.js";
|
||||
import { prettyGenT, prettyT } from "../util/pretty.js";
|
||||
import { assign, makeGeneric, unify } from "../lib/generics/generics.js";
|
||||
import { prettyGenT } from "../lib/util/pretty.js";
|
||||
import { getDefaultTypeParser } from "../lib/parser/type_parser.js";
|
||||
|
||||
const mkType = getDefaultTypeParser();
|
||||
|
||||
// a -> Int
|
||||
const a_to_Int = makeGeneric(a => fnType(() => a)(() => Int));
|
||||
console.log((prettyGenT(a_to_Int))); // ∀a: (a -> Int)
|
||||
// Bool -> Int
|
||||
const Bool_to_Int = makeGeneric(() => fnType(() => lsType(() =>Bool))(() => Int));
|
||||
console.log((prettyGenT(Bool_to_Int))); // ∀: ([Bool] -> Int)
|
||||
console.log("should be: [Bool] -> Int")
|
||||
console.log(prettyGenT(unify(a_to_Int, Bool_to_Int)));
|
||||
console.log(prettyGenT(
|
||||
unify(
|
||||
mkType("∀a: (a -> Int)"),
|
||||
makeGeneric(() => mkType("[Bool] -> Int")),
|
||||
)
|
||||
));
|
||||
|
||||
// (a -> a) -> b
|
||||
const fnType2 = makeGeneric((a,b) => fnType(() => fnType(a)(a))(() => b));
|
||||
// (Bool -> Bool) -> a
|
||||
const fnType3 = makeGeneric(a => fnType(() => fnType(Bool)(Bool))(() => a));
|
||||
console.log("should be: (Bool -> Bool) -> a");
|
||||
console.log(prettyT(unify(fnType2, fnType3)));
|
||||
console.log(prettyGenT(
|
||||
unify(
|
||||
mkType("∀a,b: (a -> a) -> b"),
|
||||
mkType("∀a: (Bool -> Bool) -> a"),
|
||||
)
|
||||
));
|
||||
|
||||
// (a -> b) -> [a] -> [b]
|
||||
const mapFnType = makeGeneric((a,b) =>
|
||||
fnType
|
||||
(fnType(() => a)(() => b))
|
||||
(fnType(() => lsType(() =>a))(() => lsType(() =>b))))
|
||||
// a -> a
|
||||
const idFnType = makeGeneric((_,__,c) =>
|
||||
fnType(() => c)(() => c));
|
||||
console.log("should be: [c] -> [c]");
|
||||
console.log(prettyT(assign(mapFnType, idFnType)));
|
||||
console.log("should be: [a] -> [a]");
|
||||
console.log(prettyGenT(
|
||||
assign(
|
||||
mkType("∀a,b: (a -> b) -> [a] -> [b]"),
|
||||
mkType("∀a: a -> a")
|
||||
)
|
||||
));
|
||||
|
||||
// (a -> Int) -> [a] -> a
|
||||
const weirdFnType = makeGeneric(a =>
|
||||
fnType
|
||||
(fnType(() => a)(() => Int))
|
||||
(fnType
|
||||
(lsType(() =>a))
|
||||
(a)))
|
||||
// we call this function with parameter of type (b -> b) ...
|
||||
// giving these substitutions:
|
||||
// a := b
|
||||
// b := Int
|
||||
console.log("should be: [Int] -> Int");
|
||||
console.log(prettyT(assign(weirdFnType, idFnType)));
|
||||
console.log(prettyGenT(
|
||||
assign(
|
||||
mkType("∀a: (a -> Int) -> [a] -> a"),
|
||||
mkType("∀a: a -> a")
|
||||
)
|
||||
));
|
||||
|
|
|
|||
|
|
@ -1,60 +0,0 @@
|
|||
import { assign, makeGeneric, unify } from "../generics/generics.js";
|
||||
import { Bool, Int } from "../primitives/types.js";
|
||||
import { newLeft, newRight, match } from "../structures/sum.js";
|
||||
import { fnType, sumType } from "../structures/types.js";
|
||||
import { pretty } from '../util/pretty.js';
|
||||
|
||||
const IntOrBool = sumType(() => Int)(() => Bool);
|
||||
|
||||
|
||||
// console.log(int5);
|
||||
|
||||
console.log(pretty(unify(
|
||||
makeGeneric(() => IntOrBool),
|
||||
makeGeneric(a => sumType(() => Int)(() => a)),
|
||||
)));
|
||||
|
||||
const cipFunction = (x) => {
|
||||
return match(x)({
|
||||
left: x_as_int => (x_as_int === 5),
|
||||
right: x_as_bool => false,
|
||||
});
|
||||
}
|
||||
|
||||
const cipFunctionType = fnType
|
||||
(IntOrBool) // in
|
||||
(Bool);
|
||||
|
||||
// console.log(cipFunctionType);
|
||||
// console.log(IntOrBool);
|
||||
|
||||
console.log(assign(
|
||||
makeGeneric(() => cipFunctionType),
|
||||
makeGeneric(() => IntOrBool),
|
||||
));
|
||||
|
||||
console.log("calling newLeft with Int:");
|
||||
const typeAtCallSite = assign(
|
||||
makeGeneric((a, b) =>
|
||||
fnType
|
||||
(a)
|
||||
(sumType(() => a)(() => b))
|
||||
),
|
||||
makeGeneric(() => Int));
|
||||
console.log(pretty(typeAtCallSite));
|
||||
|
||||
|
||||
console.log("calling cipFunction:");
|
||||
console.log(pretty(assign(
|
||||
makeGeneric(() => cipFunctionType),
|
||||
typeAtCallSite,
|
||||
)));
|
||||
|
||||
console.log("valid function calls:");
|
||||
console.log(cipFunction(newLeft(5)));
|
||||
console.log(cipFunction(newLeft(7)));
|
||||
console.log(cipFunction(newRight(true)));
|
||||
|
||||
console.log("invalid function calls:");
|
||||
console.log(cipFunction(5));
|
||||
console.log(cipFunction(newLeft("abc")));
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
import { assign } from "../generics/generics.js";
|
||||
import { makeGeneric } from "../generics/generics.js";
|
||||
import { Double, Int } from "../primitives/types.js";
|
||||
import { fnType } from "../structures/types.js";
|
||||
import { pretty } from '../util/pretty.js';
|
||||
import { getMul, NumInstances } from "../typeclasses/num.js";
|
||||
import { numDictType } from "./num_type.js";
|
||||
|
||||
const square = numDict => x => getMul(numDict)(x)(x);
|
||||
|
||||
// NumDict a -> a -> a
|
||||
const squareFnType = makeGeneric(a =>
|
||||
fnType
|
||||
(numDictType(a))
|
||||
(fnType(() => a)(() => a))
|
||||
);
|
||||
|
||||
console.log("should be: Int -> Int");
|
||||
console.log(pretty(assign(squareFnType, makeGeneric(() => numDictType(Int)))));
|
||||
|
||||
console.log("should be: Double -> Double");
|
||||
console.log(pretty(assign(squareFnType, makeGeneric(() => numDictType(Double)))));
|
||||
|
||||
// to call 'square' we need:
|
||||
// - the type of our argument (=Int)
|
||||
// - access to a mapping from types to their typeclass instantiation
|
||||
console.log("");
|
||||
console.log(square(NumInstances.get(Int))(42n)); // 1764n
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
import { parse } from "../parser/parser.js";
|
||||
import { prettyGenT, prettyT } from "../util/pretty.js";
|
||||
import { getDefaultTypeParser }from "../lib/parser/type_parser.js";
|
||||
import { prettyGenT, prettyT } from "../lib/util/pretty.js";
|
||||
|
||||
const parse = getDefaultTypeParser();
|
||||
|
||||
console.log(prettyT(parse("Int"))); // Int
|
||||
|
||||
|
|
@ -12,4 +14,3 @@ console.log(prettyT(parse("#0((Int * #0) + Unit)"))) // #0((Int ⨯ #0) + Unit)
|
|||
console.log(prettyGenT(parse("∀a: #0((a * #0) + Unit"))); // ∀a: #0((a ⨯ #0) + Unit)
|
||||
|
||||
console.log(prettyGenT(parse("∀a,b,c,d: (a*b) + (c*d)"))); // ∀a,b,c,d: ((a ⨯ b) + (c ⨯ d))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
import { select, number, input } from '@inquirer/prompts';
|
||||
import { ModulePoint } from "../lib/point.js";
|
||||
import { DefaultMap } from "../util/defaultmap.js";
|
||||
import { pretty } from '../util/pretty.js';
|
||||
import { DefaultMap } from "../lib/util/defaultmap.js";
|
||||
import { pretty } from '../lib/util/pretty.js';
|
||||
import { isFunction } from '../structures/types.js';
|
||||
import { ModuleStd } from '../stdlib.js';
|
||||
import { ModuleStd } from '../lib/stdlib.js';
|
||||
import { Double, GenericType, Int, SymbolT, Type } from "../primitives/types.js";
|
||||
import { eqType } from '../primitives/type.js';
|
||||
import { Top } from "../primitives/types.js";
|
||||
import { assignFn, makeGeneric, onlyOccurring } from '../generics/generics.js';
|
||||
import { prettyT } from '../util/pretty.js';
|
||||
import { assignFn, makeGeneric, onlyOccurring } from '../lib/generics/generics.js';
|
||||
import { prettyT } from '../lib/util/pretty.js';
|
||||
import { genUUID } from '../lib/util/random.js';
|
||||
|
||||
|
||||
// import {emitKeypressEvents} from 'node:readline';
|
||||
|
|
@ -289,7 +290,7 @@ async function createInstance(t) {
|
|||
else if (eqType(t)(SymbolT)) {
|
||||
console.log("Note: you are creating a new Symbol. Even if the description matches that of another symbol (e.g., \"Int\"), a new Symbol will be created that is unique and only equal to itself.");
|
||||
const symbolDescr = await input({message: "enter symbol description:"});
|
||||
return Symbol(symbolDescr);
|
||||
return symbolDescr + '__' + genUUID(16);
|
||||
}
|
||||
else {
|
||||
console.log("no prompt handler for creating new", prettyT(t));
|
||||
|
|
|
|||
13
examples/rbtree.js
Normal file
13
examples/rbtree.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import createRBTree from "functional-red-black-tree";
|
||||
|
||||
console.log("#############");
|
||||
console.log("## RB Tree ##");
|
||||
console.log("#############");
|
||||
|
||||
// just a small experiment
|
||||
console.log(
|
||||
createRBTree()
|
||||
.insert(1)
|
||||
.insert(1)
|
||||
.insert(2)
|
||||
);
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
import createTree from "functional-red-black-tree";
|
||||
|
||||
function benchmark(N) {
|
||||
// fastest
|
||||
function map() {
|
||||
let t = new Map();
|
||||
const startTime = Date.now();
|
||||
for (let i=0; i<N; ++i) {
|
||||
t.set(Math.random(), Math.random());
|
||||
}
|
||||
const endTime = Date.now();
|
||||
return endTime - startTime;
|
||||
}
|
||||
const durInPlace = map();
|
||||
console.log("in-place:", durInPlace, "ms");
|
||||
|
||||
// slower by constant factor
|
||||
function fun() {
|
||||
let t = createTree();
|
||||
const startTime = Date.now();
|
||||
for (let i=0; i<N; ++i) {
|
||||
t = t.insert(Math.random(), Math.random());
|
||||
}
|
||||
const endTime = Date.now();
|
||||
return endTime - startTime;
|
||||
}
|
||||
const durFunc = fun();
|
||||
console.log("functional:", durFunc, "ms");
|
||||
|
||||
// a bit slower still
|
||||
function funNoGC() {
|
||||
const old = new Array(N);
|
||||
let t = createTree();
|
||||
const startTime = Date.now();
|
||||
for (let i=0; i<N; ++i) {
|
||||
old[i] = t; // prevent garbage collection
|
||||
t = t.insert(Math.random(), Math.random());
|
||||
}
|
||||
const endTime = Date.now();
|
||||
return endTime - startTime;
|
||||
|
||||
}
|
||||
const durFuncNoGC = (N <= 1000000) ? funNoGC() : "";
|
||||
console.log("functional (no GC):", durFuncNoGC, "ms");
|
||||
|
||||
// slowest (won't scale)
|
||||
function copying() {
|
||||
let t = new Map();
|
||||
const startTime = Date.now();
|
||||
for (let i=0; i<N; ++i) {
|
||||
t = new Map(t);
|
||||
t.set(Math.random(), Math.random());
|
||||
}
|
||||
const endTime = Date.now();
|
||||
return endTime - startTime;
|
||||
}
|
||||
const durCopying = (N <= 50000) ? copying() : "";
|
||||
console.log("copying:", durCopying, "ms");
|
||||
|
||||
// slower than slowest
|
||||
function copyingNoGC() {
|
||||
const old = new Array(N);
|
||||
let t = new Map();
|
||||
const startTime = Date.now();
|
||||
for (let i=0; i<N; ++i) {
|
||||
old[i] = t; // prevent garbage collection
|
||||
t = new Map(t);
|
||||
t.set(Math.random(), Math.random());
|
||||
}
|
||||
const endTime = Date.now();
|
||||
return endTime - startTime;
|
||||
}
|
||||
const durCopyingNoGC = (N <= 10000) ? copyingNoGC() : "";
|
||||
console.log("copying (no GC):", durCopyingNoGC, "ms");
|
||||
|
||||
return [N, durInPlace, durFunc, durFuncNoGC, durCopying, durCopyingNoGC];
|
||||
}
|
||||
|
||||
const results = [];
|
||||
for (const N of [100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 10000000]) {
|
||||
console.log("N =", N);
|
||||
results.push(benchmark(N));
|
||||
}
|
||||
|
||||
console.log("N;in-place;functional;functional-NoGC;copying;copying-NoGC");
|
||||
for (const [N, durInPlace, durFunc, durFuncNoGC, durCopying, durCopyingNoGC] of results) {
|
||||
console.log(`${N};${durInPlace};${durFunc};${durFuncNoGC};${durCopying};${durCopyingNoGC}`);
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
import { compareTypes } from "../compare/type.js";
|
||||
import { makeGeneric, substitute, unify } from "../generics/generics.js";
|
||||
import { Double, Int, Unit } from "../primitives/types.js";
|
||||
import { fnType, lsType, prodType, setType, sumType } from "../structures/types.js";
|
||||
import { prettyGenT, prettyT } from "../util/pretty.js";
|
||||
import { compareTypes } from "../lib/compare/type.js";
|
||||
import { makeGeneric, substitute, unify } from "../lib/generics/generics.js";
|
||||
import { Double, Int, Unit } from "../lib/primitives/primitive_types.js";
|
||||
import { fnType, lsType, prodType, sumType, setType } from "../lib/structures/type_constructors.js";
|
||||
import { prettyGenT, prettyT } from "../lib/util/pretty.js";
|
||||
|
||||
Error.stackTraceLimit = Infinity;
|
||||
|
||||
// some recursive types:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { pretty } from "../util/pretty.js";
|
||||
import { newLiteral, transform, read, getReadDependencies, verifyValue } from "../versioning/value.js";
|
||||
import { merge, merge2, newSlot, overwrite } from "../versioning/slot.js";
|
||||
import createRBTree from "functional-red-black-tree";
|
||||
import { add, emptySet, RBTreeWrapper } from "../structures/set.js";
|
||||
import { compareNumbers } from "../compare/primitives.js";
|
||||
|
||||
|
|
@ -77,39 +76,20 @@ console.log(pretty({sixSevenEightSlot}));
|
|||
// console.log("########################");
|
||||
// console.log("## Heterogeneous data ##");
|
||||
// console.log("########################");
|
||||
|
||||
// // Slot<Int>
|
||||
// const numberOfSheepSlot = newSlot(Symbol('numberOfSheep'))(newLiteral(5));
|
||||
// const alternativeNumberOfSheepSlot = newSlot(Symbol('alternativeNumberOfSheep'))(newLiteral(6));
|
||||
// // Slot<String>
|
||||
// const labelSlot = newSlot(Symbol('label'))(newLiteral("number of sheep"));
|
||||
|
||||
// const combineFn = newLiteral(label => numberOfSheep => `${label}: ${numberOfSheep}`)
|
||||
|
||||
// // Slot<String>
|
||||
// const labelAndValueSlotA = overwrite(labelSlot)(
|
||||
// transform(read(numberOfSheepSlot))(
|
||||
// transform(read(labelSlot))(combineFn)));
|
||||
|
||||
// const labelAndValueSlotB = overwrite(labelSlot)(
|
||||
// transform(read(alternativeNumberOfSheepSlot))(
|
||||
// transform(read(labelSlot))(combineFn)));
|
||||
|
||||
// console.log(
|
||||
// add(add(emptySet(compareSlots(compareStrings)))(labelAndValueSlotA))(labelAndValueSlotB)
|
||||
// );
|
||||
|
||||
// merge()(labelSlot)(labelAndValueSlot)
|
||||
|
||||
|
||||
console.log("#############")
|
||||
console.log("## RB Tree ##")
|
||||
console.log("#############")
|
||||
|
||||
// just a small experiment
|
||||
console.log(
|
||||
createRBTree()
|
||||
.insert(1)
|
||||
.insert(1)
|
||||
.insert(2)
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue