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)
});