import type { Universe } from '@ephox/boss'; import { Arr, Fun, Optional } from '@ephox/katamari'; export type Looker = (universe: Universe, elem: E) => Optional; const all = (universe: Universe, look: Looker, elements: E[], f: (universe: Universe, look: Looker, head: E, tail: E[]) => Optional): Optional => { const head = elements[0]; const tail = elements.slice(1); return f(universe, look, head, tail); }; /** * Check if look returns the same element for all elements, and return it if it exists. */ const oneAll = (universe: Universe, look: Looker, elements: E[]): Optional => { return elements.length > 0 ? all(universe, look, elements, unsafeOne) : Optional.none(); }; const unsafeOne = (universe: Universe, look: Looker, head: E, tail: E[]): Optional => { const start = look(universe, head); return Arr.foldr(tail, (b, a) => { const current = look(universe, a); return commonElement(universe, b, current); }, start); }; const commonElement = (universe: Universe, start: Optional, end: Optional): Optional => { return start.bind((s) => { return end.filter(Fun.curry(universe.eq, s)); }); }; export { oneAll };