export function iter(x: Iterable) { return new BetterIterable(x); } export class BetterIterable { constructor(readonly values: Iterable) {} map(f: (_: T) => U) { const values = this.values; return new BetterIterable( (function* () { for (const value of values) { yield f(value); } })() ); } flatMap(f: (_: T) => Iterable) { const values = this.values; return new BetterIterable( (function* () { for (const value of values) { yield* f(value); } })() ); } zip(gen: Generator): BetterIterable<[T, U]> { const values = this.values; return new BetterIterable( (function* () { for (const value of values) { const { value: other } = gen.next(null); yield [value, other] as [T, U]; } })() ); } every(f: (_: T) => boolean): boolean { for (const x of this.values) { if (!f(x)) { return false; } } return true; } to_array() { return [...this.values]; } }