Higher kinded types with Flow

gcanti
gcanti
Sep 5, 2016 · 2 min read

Flow doesn’t support higher kinded types: https://github.com/facebook/flow/issues/30.

What does it means in practice?

Here’s a functor in PureScript

class Functor f where
map :: forall a b. (a -> b) -> f a -> f b

Let’s try to translate the concept to Flow

interface Functor<F> {
map<A, B>(f: (a: A) => B, fa: F<A>): F<B>
}

Unfortunately Flow raises the following error

map<A, B>(f: (a: A) => B, fa: F<A>): F<B>
^^^^ Incorrect number of type parameters (expected 0)

There’s no way to define F as a unary type constructor, see Kind (type theory)

interface Functor<F<*>> {
map<A, B>(f: (a: A) => B, fa: F<A>): F<B>
}
interface Functor<F<*>> {
^ Unexpected token <

Here I present a way of faking higher kinded types based on the paper Lightweight higher-kinded polymorphism and inspired by elm-brands.

The recipe

class HKT<F, A> {}

Note that F and A are phantom types.

Now I can define the functor type class without Flow complaining

interface Functor<F> {
map<A, B>(f: (a: A) => B, fa: HKT<F, A>): HKT<F, B>
}

As an example, let’s implement the Maybe functor, we need

  • a nominal type for F (let’s call it IsMaybe)
  • a way to put a value of type ?A into Maybe<A> (let’s call it inj)
  • a way to get back the value from Maybe<A> (let’s call it prj)
class IsMaybe {}type Maybe<A> = HKT<IsMaybe, A>;function inj<A>(a: ?A): Maybe<A> {
return ((a: any): Maybe<A>)
}
function prj<A>(fa: Maybe<A>): ?A {
return ((fa: any): ?A)
}

Finally we can implement the functor instance

const Nothing: Maybe<any> = inj(null)function map<A, B>(f: (a: A) => B, fa: Maybe<A>): Maybe<B> {
const a = prj(fa)
return a == null ? Nothing : inj(f(a))
}
map(n => n + 1, Nothing) // => null
map(n => n + 1, inj(3)) // => 4

Using this trick I wrote an implementation of common algebraic types: flow-static-land

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store