Last active
March 1, 2021 05:58
-
-
Save baetheus/b1aa9292de6f5f53fb6c9721b2c692d3 to your computer and use it in GitHub Desktop.
Combination of pelotom hkts and fpts HKT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Option | |
| export type None = { tag: "None" }; | |
| export type Some<A> = { tag: "Some"; value: A }; | |
| export type Option<A> = None | Some<A>; | |
| // Either | |
| export type Left<L> = { tag: "Left"; left: L }; | |
| export type Right<R> = { tag: "Right"; right: R }; | |
| export type Either<L, R> = Left<L> | Right<R>; | |
| // HKT | |
| export interface Types1<A> { | |
| Option: Option<A>; | |
| } | |
| export interface Types2<A, B> { | |
| Either: Either<A, B>; | |
| } | |
| export type URIS1 = keyof Types1<any>; | |
| export type URIS2 = keyof Types2<any, any>; | |
| export type URIS = URIS1 | URIS2; | |
| export type TypeMap1<URI extends URIS1, A> = Types1<A>[URI]; | |
| export type TypeMap2<URI extends URIS2, A, B> = Types2<A, B>[URI]; | |
| // Substitution | |
| declare const index: unique symbol; | |
| export interface _<N extends number = 0> { | |
| [index]: N; | |
| } | |
| export type $<URI extends URIS, S extends any[]> = URI extends URIS1 | |
| ? Types1<S[0]>[URI] | |
| : URI extends URIS2 ? Types2<S[0], S[1]>[URI] | |
| : never; | |
| // Functor | |
| export type FunctorFn<URI> = URI extends URIS1 | |
| ? <A, B>(fab: (a: A) => B) => (ma: $<URI, [A]>) => $<URI, [B]> | |
| : URI extends URIS2 | |
| ? <A, B>(fab: (a: A) => B) => <Z>(ma: $<URI, [Z, A]>) => $<URI, [Z, B]> | |
| : never; | |
| const f1: FunctorFn<"Option"> = (fab) => | |
| (ma) => ma.tag === "None" ? ma : { tag: "Some", value: fab(ma.value) }; | |
| // Inferred: <A, B>(fab: (a: A) => B) => (ma: Option<A>) => Option<B> | |
| const f2: FunctorFn<"Either"> = (fab) => | |
| (ma) => ma.tag === "Left" ? ma : { tag: "Right", right: fab(ma.right) }; | |
| // Inferred: <A, B>(fab: (a: A) => B) => <Z>(ma: Either<Z, A>) => Either<Z, B> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment