import { Functor } from './functor'; import { curry } from '../curry'; export abstract class Applicative extends Functor { public abstract override fmap(f: (a: a) => b): Applicative; public abstract ap(this: Applicative<(a: a) => b>, a: Applicative): Applicative; public abstract bind(f: (a: a) => Applicative): Applicative; } export namespace Applicative { export declare function pure(a: a): Applicative; export function ap(af: Applicative<(a: a) => b>, aa: Applicative): Applicative; export function ap(af: Applicative<(a: a) => b>): (aa: Applicative) => Applicative; export function ap(af: Applicative<(a: a) => b>, aa?: Applicative): Applicative | ((aa: Applicative) => Applicative) { return aa ? af.bind(f => aa.fmap(curry(f))) : (aa: Applicative) => ap(af, aa); } }