import { genOf } from "./constructors"; import { map_ } from "./functor"; import { chain_ } from "./monad"; /* * ------------------------------------------- * Apply Iterable * ------------------------------------------- */ export const zipWith_ = (fa: Iterable, fb: Iterable, f: (a: A, b: B) => C): Iterable => ({ [Symbol.iterator]() { let done = false; const ia = fa[Symbol.iterator](); const ib = fb[Symbol.iterator](); return { next() { if (done) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return this.return!(); } const va = ia.next(); const vb = ib.next(); return va.done || vb.done ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.return!() : { done: false, value: f(va.value, vb.value) }; }, return(value?: unknown) { if (!done) { done = true; if (typeof ia.return === "function") { ia.return(); } if (typeof ib.return === "function") { ib.return(); } } return { done: true, value }; } }; } }); export const zipWith = (fb: Iterable, f: (a: A, b: B) => C) => (fa: Iterable) => zipWith_(fa, fb, f); export const ap_ = (fab: Iterable<(a: A) => B>, fa: Iterable): Iterable => chain_(fab, (f) => map_(fa, f)); export const ap = (fa: Iterable) => (fab: Iterable<(a: A) => B>): Iterable => ap_(fab, fa); export const pure = (a: A): Iterable => ({ [Symbol.iterator]: () => genOf(a) });