Skip to content

Instantly share code, notes, and snippets.

@gcanti
Last active September 6, 2016 12:01
Show Gist options
  • Save gcanti/fc49d48eedf466bdffad85217656a5fc to your computer and use it in GitHub Desktop.
Save gcanti/fc49d48eedf466bdffad85217656a5fc to your computer and use it in GitHub Desktop.
// @flow
import { HKT } from '../HKT'
import type { Functor } from '../Functor'
class IsList {}
class Cons<A> {
head: A;
tail: ListV<A>;
constructor(head: A, tail: ListV<A>) {
this.head = head
this.tail = tail
}
//
// a method
//
map<B>(f: (a: A) => B): Cons<B> {
return new Cons(f(this.head), prj(map(f, inj(this.tail))))
}
}
const Nil: List<any> = inj(null)
type ListV<A> = null | Cons<A>;
export type List<A> = HKT<IsList, A>;
export function inj<A>(a: ListV<A>): List<A> {
return ((a: any): List<A>)
}
export function prj<A>(fa: List<A>): ListV<A> {
return ((fa: any): ListV<A>)
}
export function map<A, B>(f: (a: A) => B, fa: List<A>): List<B> {
const a = prj(fa)
if (a === null) {
return Nil
}
return inj(a.map(f)) // <= using the method after projection
}
// let's prove it
({ map }: Functor<IsList>)
const x = inj(new Cons(1, new Cons(2, null)))
console.log(map(n => n * 2, x)) // => Cons(2, Cons(4, null))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment