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.

Revisions

  1. svieira created this gist Sep 1, 2021.
    25 changes: 25 additions & 0 deletions higher-kinded-types.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,25 @@
    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'>