Functional JavaScript Experiment

This was just a functional programming experiment where I’ve implemented lots of list functions with only map, reduce and filter.


const slice = (xs, ...args) => [].slice.apply(xs, args);

const concat = (xs, ys) => [].concat.call(xs, ys);

const len = xs => xs.length;

const isEmpty = xs => !len(xs);

const head = xs => xs[0];

const tail = xs => slice(xs, 1);

const last = xs => head(slice(xs, -1));

const init = xs => slice(xs, 0, len(xs) - 1);

const take = (m, xs) => slice(xs, 0, m);

const reduce = (fn, acc, xs) => isEmpty(xs) ? acc : reduce(fn, fn(acc, head(xs)), tail(xs));

const map = (fn, xs) => isEmpty(xs) ? xs : reduce((acc, x) => concat(acc, [fn(x)]), [], xs);

const filter = (fn, xs) => isEmpty(xs) ? xs : reduce((acc, x) => (fn(x) ? concat(acc, [x]) : acc), [], xs);

const drop = (fn, xs) => filter(x => !fn(x), xs);

const best = (fn, xs) => isEmpty(xs) ? xs : reduce((prev, next) => fn(prev, next) ? prev : next, xs[0], xs);

const compose = (f, g) => xs => f(g(xs));

const composeAll = fns => reduce((f, g) => xs => f(g(xs)), head(fns), tail(fns));

const pipe = (f, g) => compose(g, f);

const pipeAll = fns => composeAll(fns.reverse());

const partition = (fn, xs) => reduce((acc, x) => (fn(x) ? acc[0].push(x) : acc[1].push(x), acc), [[], []], xs);

const every = (fn, xs) => reduce((acc, x) => acc && fn(x), true, xs);

const any = (fn, xs) => reduce((acc, x) => fn(x) || acc, false, xs);

You can see the source code and tests here: guumaster/functional-javascript-experiment.