Skip to content

Instantly share code, notes, and snippets.

@dewey92
Last active November 27, 2018 10:35
Show Gist options
  • Select an option

  • Save dewey92/a89ac0c72e54124ba1efa094e9c5dedf to your computer and use it in GitHub Desktop.

Select an option

Save dewey92/a89ac0c72e54124ba1efa094e9c5dedf to your computer and use it in GitHub Desktop.
Functor in a very naive way
type Tree<A> = Leaf<A> | Branch<A>;
type Leaf<A> = { _f: 'tree', kind: 'leaf', value: A };
type Branch<A> = { _f: 'tree', kind: 'branch', left: Tree<A>, right: Tree<A> };
function mapTree<A, B>(map: (val: A) => B, tree: Tree<A>): Tree<B> {
switch (tree.kind) {
case 'leaf':
return leaf(map(tree.value));
case 'branch':
return branch(
mapTree(map, tree.left),
mapTree(map, tree.right)
)
}
}
const leaf = <A>(value: A): Leaf<A> => ({
_f: 'tree',
kind: 'leaf',
value
});
const branch = <A>(left: Tree<A>, right: Tree<A>): Branch<A> => ({
_f: 'tree',
kind: 'branch',
left,
right
});
const treeA: Tree<number> = branch(
leaf(1),
branch(
leaf(2),
leaf(3)
)
);
const incr = x => x + 1;
console.log('Tree', fmap(incr, treeA));
type List<A> = Nil | Cons<A>
type Nil = { _f: 'list', kind: 'nil' };
type Cons<A> = { _f: 'list', kind: 'cons', value: A, tail: List<A> };
function mapList<A, B>(map: (val: A) => B, list: List<A>): List<B> {
switch (list.kind) {
case 'nil':
return nil();
case 'cons':
return cons(map(list.value), mapList(map, list.tail));
}
}
const nil = (): Nil => ({ _f: 'list', kind: 'nil' });
const cons = <A>(value: A, tail: List<A>): Cons<A> => ({
_f: 'list',
kind: "cons",
value,
tail
})
const listA: List<number> = cons(1, cons(2, nil()));
console.log('List: ', fmap(incr, listA));
type Functor<F, A> = { _f: string };
function fmap<A, B>(fn: (val: A) => B, functor: Tree<A> | List<A>) {
switch (functor._f) {
case 'list': return mapList(fn, functor);
case 'tree': return mapTree(fn, functor);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment