import type { Eq } from "@principia/prelude/Eq";
import type { Predicate } from "../Function";
import { not } from "../Function";
interface Next {
readonly done?: boolean;
readonly value: A;
}
/*
* -------------------------------------------
* Set Guards
* -------------------------------------------
*/
/**
* @since 1.0.0
*/
export const some_ = (set: ReadonlySet, predicate: Predicate) => {
const values = set.values();
let e: Next;
let found = false;
while (!found && !(e = values.next()).done) {
found = predicate(e.value);
}
return found;
};
/**
* @since 1.0.0
*/
export const some = (predicate: Predicate) => (set: ReadonlySet) => some_(set, predicate);
/**
* @since 1.0.0
*/
export const every_ = (set: ReadonlySet, predicate: Predicate) => not(some(not(predicate)))(set);
/**
* @since 1.0.0
*/
export const every = (predicate: Predicate) => (set: ReadonlySet) => every_(set, predicate);
/**
* Test if a value is a member of a set
*
* @since 1.0.0
*/
export const elem_ = (E: Eq) => (set: ReadonlySet, a: A): boolean => {
const values = set.values();
let e: Next;
let found = false;
while (!found && !(e = values.next()).done) {
found = E.equals(a)(e.value);
}
return found;
};
/**
* Test if a value is a member of a set
*
* @since 1.0.0
*/
export const elem = (E: Eq) => (a: A) => (set: ReadonlySet): boolean => elem_(E)(set, a);
/**
* `true` if and only if every element in the first set is an element of the second set
*
* @since 1.0.0
*/
export const isSubset = (E: Eq): ((that: ReadonlySet) => (me: ReadonlySet) => boolean) => {
const elemE = elem(E);
return (that) => every((a: A) => elemE(a)(that));
};