import type * as P from "@principia/prelude"; import * as HKT from "@principia/prelude/HKT"; import { mapBoth_, mapBothSeq_ } from "./apply"; import { Functor } from "./functor"; import type { LazyPromise, URI, V } from "./model"; import { unit } from "./unit"; /* * ------------------------------------------- * Applicative LazyPromise * ------------------------------------------- */ /** * ```haskell * both_ :: Apply f => (f a, f b) -> f (a, b) * ``` * * Applies both `LazyPromise`s and collects their results into a tuple * * @category Apply * @since 1.0.0 */ export const both_ = (fa: LazyPromise, fb: LazyPromise): LazyPromise => mapBoth_(fa, fb, (a, b) => [a, b]); /** * ```haskell * both :: Apply f => f b -> f a -> f (a, b) * ``` * * Applies both `LazyPromise`s and collects their results into a tuple * * @category Apply * @since 1.0.0 */ export const both = (fb: LazyPromise) => (fa: LazyPromise): LazyPromise => both_(fa, fb); /** * ```haskell * bothSeq_ :: Apply f => (f a, f b) -> f (a, b) * ``` * * Sequentially applies both `LazyPromise`s and collects their results into a tuple. For a parallel version, see `both_` * * @category Apply * @since 1.0.0 */ export const bothSeq_ = (fa: LazyPromise, fb: LazyPromise): LazyPromise => mapBothSeq_(fa, fb, (a, b) => [a, b]); /** * ```haskell * bothSeq :: Apply f => f b -> f a -> f (a, b) * ``` * * Sequentially applies both `LazyPromise`s and collects their results into a tuple. For a parallel version, see `both` * * @category Apply * @since 1.0.0 */ export const bothSeq = (fb: LazyPromise) => (fa: LazyPromise): LazyPromise => bothSeq_(fa, fb); /** * ```haskell * pure :: a -> LazyPromise a * ``` * * Lifts a pure value into a `LazyPromise` * * @category Applicative * @since 1.0.0 */ export const pure = (a: A): LazyPromise => () => Promise.resolve(a); export const ApplicativePar: P.Applicative<[URI], V> = HKT.instance({ ...Functor, both_, both, unit }); export const ApplicativeSeq: P.Applicative<[URI], V> = HKT.instance({ ...Functor, both_: bothSeq_, both: bothSeq, unit });