fp-ts-bracket
Version:
Bracket monad for fp-ts
464 lines (463 loc) • 13.5 kB
JavaScript
;
/**
* The Bracket module provides provides a monadic interface over TE.bracket.
*
* @since 1.0.0
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.traverseArray = exports.traverseReadonlyArrayWithIndex = exports.traverseReadonlyNonEmptyArrayWithIndex = exports.apSSeq = exports.apS = exports.let = exports.bindTo = exports.bind = exports.Do = exports.tapTask = exports.tapEither = exports.tapIO = exports.tap = exports.flatMap = exports.MonadTask = exports.MonadIO = exports.Monad = exports.Chain = exports.sequenceS = exports.sequenceT = exports.apSecond = exports.apFirst = exports.ap = exports.ApplicativePar = exports.ApplyPar = exports.sequenceSSeq = exports.sequenceTSeq = exports.apSecondSeq = exports.apFirstSeq = exports.ApplicativeSeq = exports.ApplySeq = exports.asUnit = exports.flap = exports.as = exports.map = exports.Functor = exports.FromEither = exports.fromEither = exports.fromAcquire = exports.fromTaskEither = exports.FromTask = exports.fromTask = exports.FromIO = exports.fromIO = exports.noDispose = exports.of = exports.Pointed = exports.use = exports.Bracket = exports.URI = void 0;
exports.sequenceSeqArray = exports.traverseSeqArray = exports.traverseSeqReadonlyArrayWithIndex = exports.traverseSeqReadonlyNonEmptyArrayWithIndex = exports.sequenceArray = void 0;
const Apply_1 = require("fp-ts/lib/Apply");
const Chain_1 = require("fp-ts/lib/Chain");
const E = __importStar(require("fp-ts/lib/Either"));
const function_1 = require("fp-ts/lib/function");
const Functor_1 = require("fp-ts/lib/Functor");
const O = __importStar(require("fp-ts/lib/Option"));
const RA = __importStar(require("fp-ts/lib/ReadonlyArray"));
const RNEA = __importStar(require("fp-ts/lib/ReadonlyNonEmptyArray"));
const TE = __importStar(require("fp-ts/lib/TaskEither"));
const internal_1 = require("./internal");
const internalGenreics_1 = require("./internalGenreics");
/**
* @category type lambdas
* @since 1.0.0
*/
exports.URI = "Bracket";
/**
* @category instances
* @since 1.0.0
*/
const Bracket = (acquire, dispose) => (use) => TE.bracket(acquire, use, dispose);
exports.Bracket = Bracket;
/**
* @category utils
* @since 1.0.0
*/
const use = (use) => (bracket) => bracket(use);
exports.use = use;
/**
* @category instances
* @since 1.0.0
*/
exports.Pointed = {
URI: exports.URI,
of: (x) => (use) => use(x),
};
/**
* @category constructors
* @since 1.0.0
*/
const of = (x) => exports.Pointed.of(x);
exports.of = of;
/**
* @category utils
* @since 1.0.0
*/
const noDispose = () => TE.of(undefined);
exports.noDispose = noDispose;
/**
* @category conversions
* @since 1.0.0
*/
const fromIO = (fa) => (0, exports.Bracket)(TE.fromIO(fa), exports.noDispose);
exports.fromIO = fromIO;
/**
* @category instances
* @since 1.0.0
*/
exports.FromIO = {
URI: exports.URI,
fromIO: exports.fromIO,
};
/**
* @category conversions
* @since 1.0.0
*/
const fromTask = (fa) => (0, exports.Bracket)(TE.fromTask(fa), exports.noDispose);
exports.fromTask = fromTask;
/**
* @category instances
* @since 1.0.0
*/
exports.FromTask = {
URI: exports.URI,
fromIO: exports.fromIO,
fromTask: exports.fromTask,
};
/**
* @category conversions
* @since 1.0.0
*/
const fromTaskEither = (fa) => (0, exports.Bracket)(fa, exports.noDispose);
exports.fromTaskEither = fromTaskEither;
/**
* alias for fromTaskEither
*
* @category constructors
* @since 1.0.0
*/
exports.fromAcquire = exports.fromTaskEither;
/**
* @category conversions
* @since 1.0.0
*/
const fromEither = (fa) => (0, exports.Bracket)(TE.fromEither(fa), exports.noDispose);
exports.fromEither = fromEither;
/**
* @category instances
* @since 1.0.0
*/
exports.FromEither = {
URI: exports.URI,
fromEither: exports.fromEither,
};
/**
* @category instances
* @since 1.0.0
*/
exports.Functor = {
URI: exports.URI,
map: (fa, f) => (use) => fa((a) => use(f(a))),
};
/**
* @category mapping
* @since 1.0.0
*/
const map = (f) => (fa) => exports.Functor.map(fa, f);
exports.map = map;
/**
* Maps the value to the specified constant value.
*
* @category mapping
* @since 1.0.0
*/
exports.as = (0, internalGenreics_1.dual)(2, (0, internal_1.as)(exports.Functor));
/**
* @category mapping
* @since 1.0.0
*/
exports.flap = (0, Functor_1.flap)(exports.Functor);
/**
* Maps every value to the void constant value.
*
* @category mapping
* @since 1.0.0
*/
exports.asUnit = (0, internal_1.asUnit)(exports.Functor);
// -------------------------------------------------------------------------------------
// apply in sequence
// -------------------------------------------------------------------------------------
/**
* @category instances
* @since 1.0.0
*/
exports.ApplySeq = {
...exports.Functor,
ap: (fab, fa) => (use) => fab((ab) => fa((a) => use(ab(a)))),
};
/**
* Runs computations sequentially.
*
* @category instances
* @since 1.0.0
*/
exports.ApplicativeSeq = {
...exports.Pointed,
...exports.ApplySeq,
};
/**
* @category apply
* @since 1.0.0
*/
exports.apFirstSeq = (0, Apply_1.apFirst)(exports.ApplySeq);
/**
* @category apply
* @since 1.0.0
*/
exports.apSecondSeq = (0, Apply_1.apSecond)(exports.ApplySeq);
/**
* @category sequencing
* @since 1.0.0
*/
exports.sequenceTSeq = (0, Apply_1.sequenceT)(exports.ApplySeq);
/**
* @category sequencing
* @since 1.0.0
*/
exports.sequenceSSeq = (0, Apply_1.sequenceS)(exports.ApplySeq);
// -------------------------------------------------------------------------------------
// apply in parallel
// -------------------------------------------------------------------------------------
/**
* @category instances
* @since 1.0.0
*/
exports.ApplyPar = {
...exports.Functor,
ap: (fab, fa) => (use) => () => {
let ab = O.none;
let a = O.none;
let resolvedFa = O.none;
let resolveFa = (value) => {
resolvedFa = O.some(value);
};
let resolvedFab = O.none;
let resolveFab = (value) => {
resolvedFab = O.some(value);
};
const promiseFa = fa((x) => () => {
if (O.isSome(resolvedFa)) {
return Promise.resolve(resolvedFa.value);
}
if (O.isSome(ab)) {
return use(ab.value(x))();
}
return new Promise((resolve) => {
a = O.some(x);
resolveFa = resolve;
});
})().then((ea) => {
resolveFab(ea);
return ea;
});
const promiseFab = fab((f) => () => {
if (O.isSome(resolvedFab)) {
return Promise.resolve(resolvedFab.value);
}
if (O.isSome(a)) {
return use(f(a.value))().then((ret) => {
resolveFa(ret);
return promiseFa.then((retFa) => (0, function_1.pipe)(retFa, E.apSecond(ret)));
});
}
return new Promise((resolve) => {
ab = O.some(f);
resolveFab = resolve;
});
})().then((eab) => {
resolveFa(eab);
return eab;
});
return Promise.all([promiseFab, promiseFa]).then(([eab]) => eab);
},
};
/**
* @category instances
* @since 1.0.0
*/
exports.ApplicativePar = { ...exports.Pointed, ...exports.ApplyPar };
/**
* @category apply
* @since 1.0.0
*/
const ap = (fa) => (fab) => exports.ApplyPar.ap(fab, fa);
exports.ap = ap;
/**
* @category apply
* @since 1.0.0
*/
exports.apFirst = (0, Apply_1.apFirst)(exports.ApplyPar);
/**
* @category apply
* @since 1.0.0
*/
exports.apSecond = (0, Apply_1.apSecond)(exports.ApplyPar);
/**
* @category sequencing
* @since 1.0.0
*/
exports.sequenceT = (0, Apply_1.sequenceT)(exports.ApplyPar);
/**
* @category sequencing
* @since 1.0.0
*/
exports.sequenceS = (0, Apply_1.sequenceS)(exports.ApplyPar);
// -------------------------------------------------------------------------------------
// monad
// -------------------------------------------------------------------------------------
/**
* @category instances
* @since 1.0.0
*/
exports.Chain = {
...exports.ApplySeq,
chain: (fa, f) => (use) => fa((a) => f(a)(use)),
};
/**
* @category instances
* @since 1.0.0
*/
exports.Monad = {
...exports.Pointed,
...exports.Chain,
};
/**
* @category instances
* @since 1.0.0
*/
exports.MonadIO = {
...exports.Monad,
fromIO: exports.fromIO,
};
/**
* @category instances
* @since 1.0.0
*/
exports.MonadTask = {
...exports.MonadIO,
fromTask: exports.fromTask,
};
/**
* @category sequencing
* @since 1.0.0
*/
const flatMap = (f) => (fa) => exports.Chain.chain(fa, f);
exports.flatMap = flatMap;
/**
* Composes computations in sequence, using the return value of one computation to determine the next computation and
* keeping only the result of the first.
*
* @category combinators
* @since 1.0.0
*/
exports.tap = (0, internalGenreics_1.dual)(2, (0, internal_1.tap)(exports.Chain));
/**
* @category combinators
* @since 1.0.0
*/
exports.tapIO = (0, internalGenreics_1.dual)(2, (0, internal_1.tapIO)(exports.FromIO, exports.Chain));
/**
* @category combinators
* @since 1.0.0
*/
exports.tapEither = (0, internalGenreics_1.dual)(2, (0, internal_1.tapEither)(exports.FromEither, exports.Chain));
/**
* @category combinators
* @since 1.0.0
*/
exports.tapTask = (0, internalGenreics_1.dual)(2, (0, internal_1.tapTask)(exports.FromTask, exports.Chain));
// -------------------------------------------------------------------------------------
// do notation
// -------------------------------------------------------------------------------------
/**
* @category do notation
* @since 1.0.0
*/
exports.Do = (0, exports.of)({});
/**
* @category do notation
* @since 1.0.0
*/
exports.bind = (0, Chain_1.bind)(exports.Chain);
/**
* @category do notation
* @since 1.0.0
*/
exports.bindTo = (0, Functor_1.bindTo)(exports.Functor);
const _let = (0, Functor_1.let)(exports.Functor);
exports.let = _let;
/**
* @category do notation
* @since 1.0.0
*/
exports.apS = (0, Apply_1.apS)(exports.ApplyPar);
/**
* @category do notation
* @since 1.0.0
*/
exports.apSSeq = (0, Apply_1.apS)(exports.ApplySeq);
// -------------------------------------------------------------------------------------
// array utils
// -------------------------------------------------------------------------------------
// In parallel
/**
* Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`.
*
* @category traversing
* @since 1.0.0
*/
exports.traverseReadonlyNonEmptyArrayWithIndex = RNEA.traverseWithIndex(exports.ApplicativePar);
/**
* Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`.
*
* @category traversing
* @since 1.0.0
*/
exports.traverseReadonlyArrayWithIndex = RA.traverseWithIndex(exports.ApplicativePar);
/**
* Equivalent to `ReadonlyArray#traverse(ApplicativePar)`.
*
* @category traversing
* @since 1.0.0
*/
exports.traverseArray = RA.traverse(exports.ApplicativePar);
/**
* Equivalent to `ReadonlyArray#sequence(ApplicativePar)`.
*
* @category traversing
* @since 1.0.0
*/
exports.sequenceArray = RA.sequence(exports.ApplicativePar);
// In sequence
/**
* Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`.
*
* @category traversing
* @since 1.0.0
*/
exports.traverseSeqReadonlyNonEmptyArrayWithIndex = RNEA.traverseWithIndex(exports.ApplicativeSeq);
/**
* Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`.
*
* @category traversing
* @since 1.0.0
*/
exports.traverseSeqReadonlyArrayWithIndex = RA.traverseWithIndex(exports.ApplicativeSeq);
/**
* Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`.
*
* @category traversing
* @since 1.0.0
*/
exports.traverseSeqArray = RA.traverse(exports.ApplicativeSeq);
/**
* Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`.
*
* @category traversing
* @since 1.0.0
*/
exports.sequenceSeqArray = RA.sequence(exports.ApplicativeSeq);