Last active
July 3, 2018 15:47
-
-
Save masaeedu/f320766ee3fc0b720ce24bfa5bb7d3c7 to your computer and use it in GitHub Desktop.
Various datatypes
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
| const fail = reason => { | |
| throw reason; | |
| }; | |
| const log = console.log; | |
| const Maybe = (() => { | |
| const k = Symbol(); | |
| // Algebra | |
| const Just = x => ({ [k]: x }); | |
| const Nothing = undefined; | |
| const match = ({ Just, Nothing }) => m => | |
| m === undefined | |
| ? Nothing | |
| : m.hasOwnProperty(k) | |
| ? Just(m[k]) | |
| : fail("Invalid Maybe value"); | |
| // Functor | |
| const map = f => match({ Nothing, Just: x => Just(f(x)) }); | |
| return { Just, Nothing, match, map }; | |
| })(); | |
| const List = (() => { | |
| // Algebra | |
| const Nil = undefined; | |
| const Cons = x => xs => ({ x, xs }); | |
| const match = ({ Nil, Cons }) => l => { | |
| if (l === undefined) return Nil; | |
| const { x, xs } = l; | |
| return Cons(x)(xs); | |
| }; | |
| // Functor | |
| const map = f => match({ Nil, Cons: x => xs => Cons(f(x))(map(f)(xs)) }); | |
| return { Nil, Cons, match, map }; | |
| })(); | |
| const Tree = (() => { | |
| // Algebra | |
| const Node = label => forest => ({ label, forest }); | |
| const match = ({ Node }) => ({ label, forest }) => Node(label)(forest); | |
| // Functor | |
| const Arr = { map: f => xs => xs.map(f) }; // need the array functor | |
| const map = f => | |
| match({ | |
| Node: l => t => Node(f(l))(Arr.map(map(f))(t)) | |
| }); | |
| return { Node, match, map }; | |
| })(); | |
| const Functor = ({ map }) => { | |
| const double = map(x => x * 2); | |
| return { map, double }; | |
| }; | |
| // Usage | |
| { | |
| const { Just, Nothing } = Maybe; | |
| const { double } = Functor(Maybe); | |
| log(double(Just(21))); // => Just(42) | |
| log(double(Nothing)); // => Nothing | |
| } | |
| { | |
| const { Nil, Cons, map } = List; | |
| const { double } = Functor(List); | |
| log(double(Cons(21)(Cons(21)(Nil)))); // => Cons(42)(Cons(42)(Nil)) | |
| log(double(Nil)); // => Nil | |
| } | |
| { | |
| const { Node, map } = Tree; | |
| const { double } = Functor(Tree); | |
| const N = Node; | |
| log(double(N(1)([N(2)([]), N(3)([])]))); // => N(2)([N(4)([]), N(6)([])]) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment