import type { Kind } from '../../kinds/index.js'; import type { Functor } from '../functor'; import type { Of } from '../of'; import type { TypeSkell } from '../../typeskell/index.js'; import type { TPair } from '../../data/pair'; import type { TArray } from '../../data/array'; export declare namespace Applicative { type $ap = TypeSkell<'F a ..x -> F (a -> b) ..y -> F b ..xy', { F: F; }>; type $apCompose = TypeSkell<'F (G a ..x) ..y -> F (G (a -> b) ..u) ..v -> F (G b ..xu) ..yv', { F: F; G: G; }>; type $liftA2 = TypeSkell<'(a b -> c) -> F a ..x -> F b ..y -> F c ..xy', { F: F; }>; type $product = TypeSkell<'F a ..x -> F b ..y -> F (Pair a b) ..xy', { F: F; Pair: TPair; }>; type $productMany = TypeSkell<'F a ..x -> Array (F a ..x) -> F (Array a) ..x', { F: F; Array: TArray; }>; } /** * Applicative is a typeclass that provides a way to apply a function in a context to a value in a context. * * Laws: * - Identity: ap (of id) v = v * - Homomorphism: ap (of f) (of x) = of (f x) * - Interchange: ap u (of y) = ap (of (\f -> f y)) u * - Composition: ap (ap (ap (of (.)) u) v) w = ap u (ap v w) */ export interface Applicative extends Functor, Of { /** * ap :: `F a -> F (a -> b) -> F b` * * @param fa `F a` * @returns `F (a -> b) -> F b` */ ap: Applicative.$ap; } export declare const apCompose: (applicative: Applicative, applicativeG: Applicative) => Applicative.$apCompose; /** * liftA2 :: `Applicative F -> (a b -> c) -> F a -> F b -> F c` */ export declare const liftA2: (applicative: Applicative) => Applicative.$liftA2; /** * product :: `Applicative F -> F a -> F b -> F (Pair a b)` */ export declare const product: (applicative: Applicative) => Applicative.$product; /** * productMany :: `Applicative F -> Iterable (F a) -> F (NonEmptyArray a)` */ export declare const productMany: (applicative: Applicative) => Applicative.$productMany;