@effect-ts/system
Version:
Effect-TS is a zero dependency set of libraries to write highly productive, purely functional TypeScript at scale.
354 lines (307 loc) • 6.32 kB
JavaScript
// ets_tracing: off
import "../../../Operator/index.mjs";
import { not } from "../../../Function/index.mjs";
import * as St from "../../../Structural/index.mjs";
import * as RB from "../RedBlackTree/index.mjs";
import * as Tp from "../Tuple/index.mjs";
export class SortedSet {
constructor(keyTree) {
this.keyTree = keyTree;
}
[Symbol.iterator]() {
return RB.keys_(this.keyTree);
}
get [St.hashSym]() {
return this.keyTree[St.hashSym];
}
[St.equalsSym](that) {
return this.keyTree[St.equalsSym](that);
}
}
export function make(K) {
return new SortedSet(RB.make(K));
}
export function add_(set, v) {
return RB.has_(set.keyTree, v) ? set : new SortedSet(RB.insert_(set.keyTree, v, true));
}
export function add(v) {
return set => add_(set, v);
}
export function remove_(set, v) {
return new SortedSet(RB.removeFirst_(set.keyTree, v));
}
export function remove(v) {
return set => remove_(set, v);
}
export function values(set) {
return RB.keys_(set.keyTree);
}
export function has_(set, v) {
return RB.has_(set.keyTree, v);
}
/**
* Apply f to each element
*/
export function forEach_(map, f) {
RB.forEach_(map.keyTree, k => {
f(k);
});
}
/**
* The set of elements which are in both the first and second set,
*
* the hash and equal of the 2 sets has to be the same
*/
export function intersection_(l, r) {
let x = make(l.keyTree.ord);
for (const k of r) {
if (has_(l, k)) {
x = add_(x, k);
}
}
return x;
}
/**
* The set of elements which are in both the first and second set
*
* @ets_data_first intersection_
*/
export function intersection(r) {
return l => intersection_(l, r);
}
/**
* Projects a Set through a function
*/
export function map_(E) {
return (set, f) => {
let r = make(E);
forEach_(set, e => {
const v = f(e);
if (!has_(r, v)) {
r = add_(r, v);
}
});
return r;
};
}
/**
* Projects a Set through a function
*
* @ets_data_first map_
*/
export function map(E) {
const m = map_(E);
return f => set => m(set, f);
}
/**
* true if one or more elements match predicate
*
* @ets_data_first some_
*/
export function some(predicate) {
return set => some_(set, predicate);
}
/**
* true if one or more elements match predicate
*/
export function some_(set, predicate) {
let found = false;
for (const e of set) {
found = predicate(e);
if (found) {
break;
}
}
return found;
}
/**
* Calculate the number of keys pairs in a set
*/
export function size(set) {
return RB.size(set.keyTree);
}
/**
* Creates an equal for a set
*/
export function equal() {
return {
equals: (x, y) => {
if (y === x) {
return true;
}
if (size(x) !== size(y)) {
return false;
}
let eq = true;
for (const vx of x) {
if (!has_(y, vx)) {
eq = false;
break;
}
}
return eq;
}
};
}
/**
* true if all elements match predicate
*
* @ets_data_first every_
*/
export function every(predicate) {
return set => every_(set, predicate);
}
/**
* true if all elements match predicate
*/
export function every_(set, predicate) {
return not(some(not(predicate)))(set);
}
/**
* Map + Flatten
*
* @ets_data_first chain_
*/
export function chain(E) {
const c = chain_(E);
return f => set => c(set, f);
}
/**
* Map + Flatten
*/
export function chain_(E) {
return (set, f) => {
let r = make(E);
forEach_(set, e => {
for (const a of f(e)) {
if (!has_(r, a)) {
r = add_(r, a);
}
}
});
return r;
};
}
/**
* `true` if and only if every element in the first set is an element of the second set,
*
* the hash and equal of the 2 sets has to be the same
*
* @ets_data_first isSubset_
*/
export function isSubset(y) {
return x => isSubset_(y, x);
}
/**
* `true` if and only if every element in the first set is an element of the second set,
*
* the hash and equal of the 2 sets has to be the same
*/
export function isSubset_(x, y) {
return every_(x, a => has_(y, a));
}
export function filter(predicate) {
return set => filter_(set, predicate);
}
export function filter_(set, predicate) {
let r = make(set.keyTree.ord);
const values_ = values(set);
let e;
while (!(e = values_.next()).done) {
const value = e.value;
if (predicate(value)) {
r = add_(r, value);
}
}
return r;
}
export function partition(predicate) {
return set => partition_(set, predicate);
}
export function partition_(set, predicate) {
const values_ = values(set);
let e;
let right = make(set.keyTree.ord);
let left = make(set.keyTree.ord);
while (!(e = values_.next()).done) {
const value = e.value;
if (predicate(value)) {
right = add_(right, value);
} else {
left = add_(left, value);
}
}
return Tp.tuple(left, right);
}
/**
* Form the set difference (`x` - `y`)
*/
export function difference_(x, y) {
let s = x;
for (const k of y) {
s = remove_(s, k);
}
return s;
}
/**
* Form the set difference (`x` - `y`)
*
* @ets_data_first difference_
*/
export function difference(y) {
return x => difference_(x, y);
}
/**
* Reduce a state over the map entries
*/
export function reduce_(set, z, f) {
return RB.reduceWithIndex_(set.keyTree, z, (z, v) => f(z, v));
}
/**
* Reduce a state over the map entries
*
* @ets_data_first reduce_
*/
export function reduce(z, f) {
return set => reduce_(set, z, f);
}
/**
* If element is present remove it, if not add it
*
* @ets_data_first toggle_
*/
export function toggle(a) {
return set => toggle_(set, a);
}
/**
* If element is present remove it, if not add it
*/
export function toggle_(set, a) {
return (has_(set, a) ? remove : add)(a)(set);
}
/**
* Form the union of two sets,
*
* the hash and equal of the 2 sets has to be the same
*/
export function union_(l, r) {
let x = make(l.keyTree.ord);
forEach_(l, a => {
x = add_(x, a);
});
for (const a of r) {
x = add_(x, a);
}
return x;
}
/**
* Form the union of two sets,
*
* the hash and equal of the 2 sets has to be the same
*
* @ets_data_first union_
*/
export function union(y) {
return x => union_(x, y);
}
//# sourceMappingURL=index.mjs.map