Skip to content

Instantly share code, notes, and snippets.

@choonkending
Last active May 22, 2020 01:24
Show Gist options
  • Save choonkending/5f61084da1b57e9e3457cec8a4fbddaf to your computer and use it in GitHub Desktop.
Save choonkending/5f61084da1b57e9e3457cec8a4fbddaf to your computer and use it in GitHub Desktop.
// https://medium.com/@gcanti/higher-kinded-types-in-typescript-static-and-fantasy-land-d41c361d0dbe
import {
TypeConstructors,
TypeConstructors2,
Kind,
Kind2,
} from "./higherKindedTypes";
export interface Functor<F extends TypeConstructors, A> {
map: <A1>(f: (a: A) => A1) => Kind<F, A1>;
}
export interface Functor2<F extends TypeConstructors2, A, B> {
map: <A1>(f: (a: A) => A1) => Kind2<F, A1, B>;
}
// Inspired by https://medium.com/@gcanti/higher-kinded-types-in-typescript-static-and-fantasy-land-d41c361d0dbe
/**
* `* -> *` constructors
*/
export interface HigherKindedType<TypeConstructor, TypeParameter> {
readonly _TypeConstructor: TypeConstructor;
readonly _TypeParameter: TypeParameter;
}
/**
* `* -> * -> *` constructors
*/
export interface HigherKindedType2<
TypeConstructor,
TypeParameter1,
TypeParameter2
> {
readonly _TypeConstructor: TypeConstructor;
readonly _TypeParameter1: TypeParameter1;
readonly _TypeParameter2: TypeParameter2;
}
/*
* Type level dictionaries for HigherKindedTypes: TypeConstructor -> concrete type
*/
/* eslint-disable @typescript-eslint/no-empty-interface */
export interface TypeConstructorToHigherKindedType<A> {}
/* eslint-enable @typescript-eslint/no-empty-interface */
/* eslint-disable @typescript-eslint/no-empty-interface */
export interface TypeConstructorToHigherKindedType2<A, B> {}
/* eslint-enable @typescript-eslint/no-empty-interface */
/* eslint-disable @typescript-eslint/no-explicit-any */
export type TypeConstructors = keyof TypeConstructorToHigherKindedType<any>;
/* eslint-enable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-explicit-any */
export type TypeConstructors2 = keyof TypeConstructorToHigherKindedType2<
any,
any
>;
/* eslint-enable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-explicit-any */
export type Kind<
TypeConstructor extends TypeConstructors,
A
> = TypeConstructor extends TypeConstructors
? TypeConstructorToHigherKindedType<A>[TypeConstructor]
: any;
/* eslint-enable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-explicit-any */
export type Kind2<
TypeConstructor extends TypeConstructors2,
A,
B
> = TypeConstructor extends TypeConstructors2
? TypeConstructorToHigherKindedType2<A, B>[TypeConstructor]
: any;
/* eslint-enable @typescript-eslint/no-explicit-any */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment