import { fnType, setType } from "./types.js"; import { Int } from "../primitives/types.js"; import { makeGeneric } from "../generics/generics.js"; import createRBTree from "functional-red-black-tree"; import { inspect } from "node:util"; export class RBTreeWrapper { constructor(tree) { this.tree = tree; } [inspect.custom](depth, options, inspect) { const entries = []; this.tree.forEach((key,val) => {entries.push(`${inspect(key)} => ${inspect(val)}`);}); return `RBTree(${this.tree.length}) {${entries.join(', ')}}`; } } // (a -> a -> Int) -> Set(a) export const emptySet = compareFn => new RBTreeWrapper(createRBTree((x, y) => compareFn(x)(y))); // const emptySetType = makeGeneric(a => fnType(fnType(a)(fnType(a)(Int)))(setType(a))); export const has = set => key => set.tree.get(key) === true; export const add = set => key => set.tree.get(key) === true ? set : new RBTreeWrapper(set.tree.insert(key, true)); export const remove = set => key => new RBTreeWrapper(set.tree.remove(key)); export const length = set => set.tree.length; export const first = set => set.tree.begin; export const last = set => set.tree.end; // test if iterator is 'done', and if not, get element and advance iterator. export const read = iter => ifNotDone => ifDone => { if (iter !== undefined && iter.valid) { return ifNotDone(iter.key)(iter.clone().next()); } else { return ifDone(); } }; export const forEach = set => fn => { set.tree.forEach(key => { fn(key); }); }; export const ModuleSet = {l:[ // // Type -> Type // ...typedFnType(setType, fnType => // fnType // /* in */ (Type) // /* out */ (Type) // ), // {i: emptySet , t: emptySetType}, // {i: emptySetType, t: GenericType }, // ...typedFnType(has, fnType => // makeGeneric(a => // fnType // /* in */ (setType(a)) // /* out */ (fnType // /* in */ (a) // /* out */ (Bool) // )), GenericType), // ...typedFnType(add, fnType => // makeGeneric(a => // fnType // /* in */ (setType(a)) // /* out */ (fnType // /* in */ (a) // /* out */ (setType(a)) // )), GenericType), ]};