@quenk/preconditions
Version:
Make data satisfy constraints before using.
74 lines • 2.66 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.reduce = exports.tuple = exports.map = exports.filter = void 0;
const lazy = require("@quenk/noni/lib/data/lazy");
const either_1 = require("@quenk/noni/lib/data/either");
const future_1 = require("@quenk/noni/lib/control/monad/future");
const array_1 = require("../result/failure/array");
const result_1 = require("../result");
/**
* filter (async).
*/
const filter = (p) => (value) => (0, future_1.parallel)(value.map(p))
.map((r) => r.reduce(filterResults, []))
.chain((values) => (0, future_1.pure)((0, result_1.succeed)(values)));
exports.filter = filter;
const filterResults = (p, c) => c instanceof either_1.Right ? p.concat(c.takeRight()) : p;
/**
* map (async).
*/
const map = (p) => (value) => future_1.Future.do(async () => {
let failed = 0;
let failures = {};
let values = [];
for (let i = 0; i < value.length; i++) {
let result = await p(value[i]);
if (result.isLeft()) {
failed++;
failures[i] = result.takeLeft();
}
else {
values[i] = result.takeRight();
}
}
return failed === 0
? (0, result_1.succeed)(values)
: (0, either_1.left)(array_1.ArrayFailure.create(failures, value, { value }));
});
exports.map = map;
/**
* tuple (async)
*/
const tuple = (list) => (value) => {
if (value.length !== list.length)
return (0, future_1.pure)((0, result_1.fail)('tuple', value));
return (0, future_1.parallel)(value.map((v, idx) => list[idx](v))).chain(results => {
let fails = results.filter(v => v.isLeft()).map(e => e.takeLeft());
if (fails.length > 0) {
let failMap = fails.reduce((p, c, k) => {
p[k] = c;
return p;
}, {});
return (0, future_1.pure)((0, either_1.left)(array_1.ArrayFailure.create(failMap, value, { value })));
}
return (0, future_1.pure)((0, result_1.succeed)(results.map(e => e.takeRight())));
});
};
exports.tuple = tuple;
/**
* reduce (async version)
*/
const reduce = (getAccum, func) => (value) => future_1.Future.do(async () => {
let accum = lazy.evaluate(getAccum);
for (let i = 0; i < value.length; i++) {
let eresult = await func(accum)(value[i]);
if (eresult.isLeft()) {
let err = eresult.takeLeft();
return (0, either_1.left)(array_1.ArrayFailure.create({ [i]: err }, value, {}));
}
accum = eresult.takeRight();
}
return (0, result_1.succeed)(accum);
});
exports.reduce = reduce;
//# sourceMappingURL=array.js.map