import { Arity1, curry2 } from '@typed/functions' import { Either } from '@typed/either' import { List } from '@typed/list' import { Maybe } from '@typed/maybe' import { chain } from './chain' import { map } from './map' /** * Apply the function contained in an Applicative to the values contained * in another Applicative. Works with all data structures supported by `chain` and * `map`. * @name ap(fn: List>, values: List): Array */ export const ap: Ap = curry2(__ap) function __ap(fn: List>, value: List): Array { return chain((f: Arity1) => map(f, value), fn) } export type Ap = { (fn: List>, list: List): Array (fn: Maybe>, maybe: Maybe): Maybe (fn: PromiseLike>, promise: PromiseLike): Promise (fn: Either>, either: Either): Either (fn: List>): (list: List) => Array (fn: Maybe>): (maybe: Maybe) => Maybe (fn: PromiseLike>): (promise: PromiseLike) => Promise (fn: Either>): (either: Either) => Either }