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