Skip to content

Instantly share code, notes, and snippets.

@svieira
Created September 1, 2021 01:10
Show Gist options
  • Save svieira/61d1b848c28d1134b9c80504af959c7d to your computer and use it in GitHub Desktop.
Save svieira/61d1b848c28d1134b9c80504af959c7d to your computer and use it in GitHub Desktop.
Higher-Kinded Type Approximation in TypeScript
type Replace<T, X, Y> = {
[k in keyof T]: T[k] extends X ? Y : T[k];
};
declare const higherKindedTypeKey: unique symbol;
type HigherKindedTypeBrand = typeof higherKindedTypeKey;
type HigherKindedType<T> = T & HigherKindedTypeBrand;
type $ = {[higherKindedTypeKey]: unknown};
type HigherKindedTypeReplace<T, X, Y> = T extends $ ? Y : Replace<T, X, Y>
type HKT<T extends HigherKindedType<any>, X, Y> = HigherKindedTypeReplace<T, X, Y>
type Monad<T> = HigherKindedType<{
map<A, B>(f: (a: A) => B): (v: HKT<T, $, A>) => HKT<T, $, B>;
lift<A>(a: A): HKT<T, $, A>;
join<A>(tta: HKT<T, $, HKT<T, $, A>>): HKT<T, $, A>;
}>
function MONAD(m: Monad<$[]>, f: (s: string) => number) {
var a = m.map(f); // (v: string[]) => number[]
var b = m.lift(1); // number[]
var c = m.join([[2], [3]]); // number[]
}
type AGenericType<T> = T[];
type AnotherGeneric<T> = T;
type F = HKT<AnotherGeneric<$>, $, '123'>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment