rivo
Version:
🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.
101 lines (91 loc) • 3.08 kB
TypeScript
import type ApFn from "./Ap";
import type { Fn1, Fn2, PartialApply } from "../../HKT";
import type { ValueOf } from "../../Obj/ValueOf";
import type { Eq, Lazied, Lazied$Get } from "../../helpers";
import type { Functor } from "../Functor";
import type { HKT, Kind } from "../HKT";
/**
* A type class for types that can be converted to a string.
*/
export type Applicative<T = unknown> = Lazied$Get<ApplicativeL<T>>;
/**
* {@link Lazied} version of {@link Applicative}.
*/
export type ApplicativeL<T = unknown> = Lazied<Kind<ApplicativeImpl[keyof ApplicativeImpl][0], T>>;
/**
* Type class constraints for type class {@link Applicative}.
*/
export interface TypeClass$$Applicative<F extends Functor> {
/**
* Apply an {@link Applicative} of a function to an {@link Applicative} of a value.
*
* **⚠️ Warning:** Correctness of the method is not fully checked, so be careful when implementing
* this method.
*
* Sig: `<F<~>, T, U>(fab: F<(x: T) => U>, f: F<T>) => F<U>`
*/
Ap: Fn2<Kind<F, Fn1>, F, F>;
/**
* Build an {@link Applicative} from a value.
*
* **⚠️ Warning:** Correctness of the method is not fully checked, so be careful when implementing
* this method.
*
* Sig: `<F<~>, T>(x: T) => F<T>`
*/
Of: Fn1<unknown, F>;
}
/**
* Implementations for type class {@link Applicative}.
*/
export interface ApplicativeImpl {}
/**
* Helper type for implementing type class {@link Applicative}.
*/
export type ImplApplicativeFor<F extends Functor, TypeClass extends TypeClass$$Applicative<F>> = [
F,
TypeClass,
];
/**
* Get the matching entry of {@link ApplicativeImpl} for `F`.
* @private
*/
type _Applicative$GetMatch<F extends Applicative> = ValueOf<{
[P in keyof ApplicativeImpl as F extends ApplicativeImpl[P][0] ? P : never]: ApplicativeImpl[P];
}>;
/**
* Get the constructor of `F` from {@link ApplicativeImpl}.
*/
export type Applicative$GetConstruct<F extends Applicative> =
Eq<F, Applicative> extends true ? Applicative
: _Applicative$GetMatch<F> extends [infer F extends HKT, unknown] ? F
: never;
/**
* The **unsafe** version of {@link Applicative$GetConstruct} (i.e. no type checking with `F`).
*/
export type Applicative$GetConstructW<F> =
F extends Applicative ? Applicative$GetConstruct<F> : never;
/**
* Get the type class of `F` from {@link ApplicativeImpl}.
*/
export type Applicative$GetTypeClass<F extends Applicative> =
_Applicative$GetMatch<F> extends [unknown, infer TypeClass] ? TypeClass : never;
/**
* The **unsafe** version of {@link Applicative$GetTypeClass} (i.e. no type checking with `F`).
*/
export type Applicative$GetTypeClassW<F> =
F extends Applicative ? Applicative$GetTypeClass<F> : never;
/***********
* Methods *
***********/
/**
* Methods for `Applicative`.
*/
export namespace Applicative {
/**
* [Fn] Apply an {@link Applicative} of a function to an {@link Applicative} of a value.
*
* Sig: `<F<~>, T, U>[f: F<T>](fab: F<(x: T) => U>) => F<U>`
*/
export type Ap<F extends Applicative> = PartialApply<ApFn, [F], "_1">;
}