Last active
October 27, 2018 06:56
-
-
Save gcanti/b7c1f86e1fac08fc45921160e135a672 to your computer and use it in GitHub Desktop.
HKTs in Flow
This file contains 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
// @flow | |
// type-level dictionary URI -> type constructor | |
export type URI2HKT<U, L, A> = { | |
Identity: Identity<A> | |
// other type constructors here... | |
// Option: Option<A>, | |
// Either: Either<L, A>, | |
// Foo: Foo<U, L, A> | |
} | |
// helper | |
export type HKT<F, U, L, A> = $ElementType<URI2HKT<U, L, A>, F> | |
// Functor is defined via HKT | |
export interface Functor<F> { | |
URI: F, | |
map<A, B, U, L>(f: (a: A) => B, fa: HKT<F, U, L, A>): HKT<F, U, L, B> | |
} | |
// a function which abstracts over Functor | |
export function lift<F, A, B, U, L>(F_: Functor<F>): (f: (a: A) => B) => (fa: HKT<F, U, L, A>) => HKT<F, U, L, B> { | |
return f => fa => F_.map(f, fa) | |
} | |
export class Identity<A> { | |
+value: A | |
constructor(value: A) { | |
this.value = value | |
} | |
map<B>(f: (a: A) => B): Identity<B> { | |
return new Identity(f(this.value)) | |
} | |
} | |
export const map = <A, B>(f: (a: A) => B, fa: Identity<A>): Identity<B> => { | |
return fa.map(f) | |
} | |
// Functor instance for Identity | |
export const identity: Functor<'Identity'> = { | |
URI: 'Identity', | |
map | |
} | |
// let's lift double to the Identity functor | |
const double = (n: number): number => n * 2 | |
const liftedIdentityDouble = lift(identity)(double) | |
const y1: number = liftedIdentityDouble(new Identity(1)) | |
/* | |
39: const y1: number = liftedIdentityDouble(new Identity(1)) | |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Identity. This type is incompatible with | |
39: const y1: number = liftedIdentityDouble(new Identity(1)) | |
^^^^^^ number | |
*/ | |
const y2: Identity<number> = liftedIdentityDouble(new Identity(1)) | |
// ok |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment