Skip to content

Instantly share code, notes, and snippets.

@KEIII
Last active August 25, 2021 10:58
Show Gist options
  • Save KEIII/cf6cf37efd9bf85d2d07ad070bee8e72 to your computer and use it in GitHub Desktop.
Save KEIII/cf6cf37efd9bf85d2d07ad070bee8e72 to your computer and use it in GitHub Desktop.
Iterators
import assert from "assert";
import { Option, isSome, none, some } from '@keiii/k-stream';
const range = (
[a, b]: [number, number],
inclusive = false
): Iterable<number> => {
assert(b >= a, "Invalid range");
const isDone = inclusive ? (x: number) => x > b : (x: number) => x >= b;
return {
[Symbol.iterator]: (): Iterator<number> => {
let current = a;
return {
next: (): IteratorResult<number> => {
return isDone(current)
? { done: true, value: current }
: { done: false, value: current++ };
},
};
},
};
};
const filterMap = <A, B>(
ia: Iterable<A>,
f: (a: A) => Option<B>,
): Iterable<B> => {
return {
[Symbol.iterator]: () => {
const i = ia[Symbol.iterator]();
let current;
const go = (): IteratorResult<B> => {
current = i.next();
if (current.done) return { done: true, value: current.value };
const x = f(current.value);
return isSome(x) ? { done: false, value: x.value } : go();
};
return { next: go };
},
};
};
const map = <A, B>(ia: Iterable<A>, f: (a: A) => B): Iterable<B> => {
return {
[Symbol.iterator]: () => {
const i = ia[Symbol.iterator]();
let current;
return {
next: () => {
current = i.next();
return current.done
? { done: true, value: current.value }
: {
done: false,
value: f(current.value),
};
},
};
},
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment