Skip to content

Instantly share code, notes, and snippets.

@andrew--r
Last active February 9, 2018 16:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andrew--r/4e9c6e73e3e488c9c7213654c4a08853 to your computer and use it in GitHub Desktop.
Save andrew--r/4e9c6e73e3e488c9c7213654c4a08853 to your computer and use it in GitHub Desktop.
const cons = (a, b) => {
const inner = (fn) => fn(a, b);
inner.valueOf = inner.toString = () => `(${a} ${b})`;
inner.isPair = true;
return inner;
};
const car = (pair) => pair((a, b) => a);
const cdr = (pair) => pair((a, b) => b);
const isNull = (x) => x === null;
const list = (...args) => args.reverse().reduce((result, item) => cons(item, result), null);
const listRef = (list, n) => n === 0 ? car(list) : listRef(cdr(list), n - 1);
const listLength = (list) => list ? (1 + listLength(cdr(list))) : 0;
const append = (a, b) => !a ? b : cons(car(a), append(cdr(a), b));
const lastItem = (list) => !cdr(list) ? car(list) : lastItem(cdr(list));
const reverse = (list) => {
const iter = (l, result) => isNull(l) ? result : iter(cdr(l), cons(car(l), result));
return iter(list, null)
};
const map = (list, fn) => isNull(list) ? list : cons(fn(car(list)), map(cdr(list), fn));
const filter = (list, matches) => {
const tail = isNull(cdr(list)) ? null : filter(cdr(list), matches);
return matches(car(list)) ? cons(car(list), tail) : tail;
};
const reduce = (list, fn, acc) => isNull(list) ? acc : reduce(cdr(list), fn, fn(acc, car(list)));
// trees
const isPair = (item) => !isNull(item) && item.isPair;
const countLeaves = (tree) => isPair(tree) ? countLeaves(car(tree)) + countLeaves(cdr(tree)) : (isNull(tree) ? 0 : 1);
const deepReverse = (tree) => reverse(map(tree, (item) => isPair(item) ? deepReverse(item) : item));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment