import { newRight } from "./sum.js"; import { newProduct } from "./product.js"; import { unit } from "../primitives/unit.js"; import { RBTreeWrapper } from "../util/rbtree_wrapper.js"; import { indent } from "../util/util.js"; // only for debugging function inspectSet(_depth, options, inspect) { const keys = []; this.tree.forEach((key) => { keys.push(inspect(key, options)); }); return `{\n${indent(keys.join(',\n'), 2)}\n}`; } // (a -> a -> Int) -> Set(a) export const emptySet = compareFn => RBTreeWrapper.new((x, y) => compareFn(x)(y), inspectSet); 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), inspectSet); export const remove = set => key => new RBTreeWrapper(set.tree.remove(key), inspectSet); export const length = set => set.tree.length; export const fold = callback => initial => set => { let acc = initial; for (const iter=set.tree.begin; iter !== undefined && iter.valid; iter.next()) { acc = callback(acc)(iter.key); } return acc; }; 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 => { if (iter !== undefined && iter.valid) { return newRight( newProduct (iter.key) (iter.clone().next()) ); } else { return newLeft(unit); } }; export const forEach = set => fn => { set.tree.forEach(key => { fn(key); }); };