const curry = f => (a, ..._) => _.length ? f(a, ..._) : (..._) => f(a, ..._);
const go1 = (a, f) => a instanceof Promise ? a.then(f) : f(a);
const go = (...args) => reduce((a, f) => f(a), args);
const pipe = (f, ...fs) => (...as) => go(f(...as), ...fs);
병렬 평가
const L = {};
L.range = function* (l) { let i = -1; while (++i < l) yield i;};
L.map = curry(function* (f, iter) { for (const a of iter) { yield go1(a, f); }});
const nop = Symbol('nop');
L.filter = curry(function* (f, iter) { for (const a of iter) { const b = go1(a, f); if (b instanceof Promise) yield b.then(b => b ? a : Promise.reject(nop)); else if (b) yield a; }});
L.entries = function* (obj) { for (const k in obj) yield [k, obj[k]];};
L.flatten = function* (iter) { for (const a of iter) { if (isIterable(a)) yield* a; else yield a; }};
L.deepFlat = function* f(iter) { for (const a of iter) { if (isIterable(a)) yield* f(a); else yield a; }};
L.flatMap = curry(pipe(L.map, L.flatten));
const map = curry(pipe(L.map, takeAll));const filter = curry(pipe(L.filter, takeAll));const find = curry((f, iter) => go( iter, L.filter(f), take(1), ([a]) => a));const flatten = pipe(L.flatten, takeAll);const flatMap = curry(pipe(L.map, flatten));
엄격한 평가
const C = {};
function noop() {}
const catchNoop = ([...arr]) => (arr.forEach(a => a instanceof Promise ? a.catch(noop) : a), arr);
C.reduce = curry((f, acc, iter) => iter ? reduce(f, acc, catchNoop(iter)) : reduce(f, catchNoop(acc)));C.take = curry((l, iter) => take(l, catchNoop(iter)));C.takeAll = C.take(Infinity);C.map = curry(pipe(L.map, C.takeAll));C.filter = curry(pipe(L.filter, C.takeAll));
참고
관련글javarecordjava예외와 에러java제네릭과 variancejavascriptLexical Scope와 ClosurejavascriptPromisejavascriptuseEffect 안에서 setInterval 사용하기