UNPKG

@typed/fp

Version:

Data Structures and Resources for fp-ts

337 lines 7.27 kB
import { getApplicativeMonoid } from 'fp-ts/Applicative'; import * as Ch from 'fp-ts/Chain'; import * as E from 'fp-ts/Either'; import * as FIO from 'fp-ts/FromIO'; import * as FT from 'fp-ts/FromTask'; import { constant, constVoid, flow, pipe } from 'fp-ts/function'; import { bindTo as bindTo_, tupled as tupled_ } from 'fp-ts/Functor'; import { isNone, none, some } from 'fp-ts/Option'; import * as RA from 'fp-ts/ReadonlyArray'; import { disposeBoth, disposeNone, settable, undisposable } from './Disposable'; /** * @since 0.9.2 * @category Constructor */ export const async = (resume) => ({ _tag: 'async', resume }); /** * @since 0.9.2 * @category Constructor */ export const fromTask = (task) => async((resume) => { const disposable = settable(); task().then((r) => { if (!disposable.isDisposed()) { disposable.addDisposable(resume(r)); } }); return disposable; }); /** * @since 0.9.2 * @category Constructor */ export const sync = (resume) => ({ _tag: 'sync', resume }); /** * @since 0.9.2 * @category Refinement */ export const isSync = (resume) => resume._tag === 'sync'; /** * @since 0.9.2 * @category Refinement */ export const isAsync = (resume) => resume._tag === 'async'; /** * @since 0.9.2 * @category Combinator */ export const ap = (fa) => (fab) => { if (isSync(fa) && isSync(fab)) { return sync(() => fab.resume()(fa.resume())); } // Concurrently return async((resume) => { const disposable = settable(); let ab = isSync(fab) ? some(fab.resume()) : none; let a = isSync(fa) ? some(fa.resume()) : none; function onReady() { if (isNone(ab) || isNone(a)) { return disposeNone(); } if (!disposable.isDisposed()) { disposable.addDisposable(resume(ab.value(a.value))); } return disposable; } if (isAsync(fab)) { disposable.addDisposable(fab.resume((f) => { ab = some(f); return onReady(); })); } if (isAsync(fa)) { disposable.addDisposable(fa.resume((x) => { a = some(x); return onReady(); })); } return disposable; }); }; /** * @since 0.9.2 * @category Deconstructor */ export const run = (f) => (resume) => isAsync(resume) ? resume.resume(f) : f(resume.resume()); /** * @since 0.9.2 * @category Deconstructor */ export const start = (f) => run(undisposable(f)); /** * @since 0.9.2 * @category Deconstructor */ export const exec = start(constVoid); /** * @since 0.9.2 * @category Deconstructor */ export const toTask = (resume) => { const task = () => { const d = settable(); const p = new Promise((resolve) => d.addDisposable(pipe(resume, start(resolve)))); p.dispose = () => d.dispose(); return p; }; return task; }; /** * @since 0.9.2 * @category Combinator */ export const chain = (f) => (resume) => isSync(resume) ? f(resume.resume()) : async((r) => resume.resume(flow(f, run(r)))); /** * @since 0.9.2 * @category Constructor */ export const of = flow(constant, sync); /** * @since 0.9.2 * @category Combinator */ export const chainRec = (f) => (value) => { let resume = f(value); while (isSync(resume)) { const either = resume.resume(); if (E.isRight(either)) { return of(either.right); } resume = f(either.left); } // Recursion is okay because Resume SHOULD be asynchronous return pipe(resume, chain(E.match(chainRec(f), of))); }; /** * @since 0.9.2 * @category Combinator */ export const race = (ra) => (rb) => { if (isSync(rb)) { return rb; } if (isSync(ra)) { return ra; } return async((resume) => { const aDisposableLazy = settable(); const bDisposable = pipe(rb, run((b) => { aDisposableLazy.dispose(); return resume(b); })); const aDisposable = pipe(ra, run((a) => { bDisposable.dispose(); return resume(a); })); aDisposableLazy.addDisposable(aDisposable); return disposeBoth(bDisposable, aDisposable); }); }; /** * @since 0.9.2 * @category URI */ export const URI = '@typed/fp/Resume'; /** * @since 0.9.2 * @category Instance */ export const Pointed = { of, }; /** * @since 0.9.2 * @category Instance */ export const Functor = { URI, map: (f) => (fa) => pipe(fa, chain(flow(f, of))), }; /** * @since 0.9.2 * @category Combinator */ export const map = Functor.map; /** * @since 0.9.2 * @category Instance */ export const Apply = { ...Functor, ap, }; /** * @since 0.9.2 * @category Instance */ export const Applicative = { ...Apply, ...Pointed, }; /** * @since 0.9.2 * @category Instance */ export const Chain = { ...Functor, chain, }; /** * @since 0.9.2 * @category Combinator */ export const chainFirst = Ch.chainFirst(Chain); /** * @since 0.9.2 * @category Instance */ export const Monad = { ...Chain, ...Pointed, }; /** * @since 0.9.2 * @category Instance */ export const ChainRec = { URI, chainRec, }; /** * @since 0.9.2 * @category Instance */ export const MonadRec = { ...Monad, chainRec, }; /** * @since 0.9.2 * @category Instance */ export const Alt = { ...Functor, alt: (snd) => (fst) => pipe(fst, race(snd())), }; /** * @since 0.9.2 * @category Instance */ export const FromIO = { URI, fromIO: sync, }; /** * @since 0.9.2 * @category Constructor */ export const fromIO = FromIO.fromIO; /** * @since 0.9.2 * @category Instance */ export const FromTask = { ...FromIO, fromTask, }; /** * @since 0.9.2 * @category Constructor */ export const Do = sync(() => Object.create(null)); /** * @since 0.9.2 * @category Combinator */ export const bindTo = bindTo_(Functor); /** * @since 0.9.2 * @category Combinator */ export const bind = Ch.bind(Monad); /** * @since 0.9.2 * @category Combinator */ export const tupled = tupled_(Functor); /** * @since 0.9.2 * @category Combinator */ export const traverseReadonlyArray = RA.traverse(Applicative); /** * @since 0.9.2 * @category Combinator */ export const traverseReadonlyArrayWithIndex = RA.traverseWithIndex(Applicative); /** * @since 0.9.2 * @category Combinator */ export const zip = traverseReadonlyArray((x) => x); /** * @since 0.9.2 * @category Combinator */ export const chainFirstTaskK = FT.chainFirstTaskK(FromTask, Chain); /** * @since 0.9.2 * @category Combinator */ export const chainTaskK = FT.chainTaskK(FromTask, Chain); /** * @since 0.9.2 * @category Constructor */ export const fromTaskK = FT.fromTaskK(FromTask); /** * @since 0.9.2 * @category Combinator */ export const chainFirstIOK = FIO.chainFirstIOK(FromIO, Chain); /** * @since 0.9.2 * @category Combinator */ export const chainIOK = FIO.chainIOK(FromIO, Chain); /** * @since 0.9.2 * @category Constructor */ export const fromIOK = FIO.fromIOK(FromIO); /** * @since 0.9.2 * @category Typeclass Constructor */ export const getMonoid = getApplicativeMonoid(Applicative); //# sourceMappingURL=Resume.js.map