Skip to content

Instantly share code, notes, and snippets.

@arian
Last active August 28, 2016 05:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save arian/7082258 to your computer and use it in GitHub Desktop.
Save arian/7082258 to your computer and use it in GitHub Desktop.
Functional JS
"use strict";
function toArray(thing) {
if (Array.isArray(thing)) return thing;
return Array.prototype.slice.call(thing);
}
function head(arr) {
return arr[0];
}
function tail(arr) {
return toArray(arr).slice(1);
}
function take(arr, num) {
return toArray(arr).slice(0, num);
}
function concat(head, tail) {
return [head].concat(tail);
}
function curry(fn) {
var args = tail(arguments);
return function() {
return fn.apply(this, args.concat(toArray(arguments)));
};
}
function foldr(fn, init, xs) {
if (xs.length === 0) return init;
return fn(head(xs), foldr(fn, init, tail(xs)));
}
function foldl(fn, init, xs) {
if (xs.length === 0) return init;
return fn(foldr(fn, init, tail(xs)), head(xs));
}
function map(fn, xs) {
var m = function(head, tail) {
return concat(fn(head), tail);
};
return foldr(m, [], xs);
}
function filter(fn, xs) {
var f = function(head, tail) {
if (fn(head)) return concat(head, tail);
return tail;
};
return foldr(f, [], xs);
}
function append(xs, ys) {
return foldr(concat, ys, xs);
}
function zipWith(fn, xs, ys) {
var step = function(xs, ys, init) {
if (xs.length === 0 || ys.length === 0) return init;
return concat(fn(head(xs), head(ys)), step(tail(xs), tail(ys), init));
};
return step(xs, ys, []);
}
function pair(x, y) {
return [x, y];
}
var zip = curry(zipWith, pair);
function lte(a, b) {
return b <= a;
}
function gt(a, b) {
return b > a;
}
function quicksort(arr) {
if (arr.length === 0) return [];
var x = head(arr), xs = tail(arr);
if (xs.length === 0) return [x];
var smallerSorted = quicksort(filter(curry(lte, x), xs));
var biggerSorted = quicksort(filter(curry(gt, x), xs));
return smallerSorted.concat(x, biggerSorted);
}
function add(a, b) {
return a + b;
}
var sum = curry(foldr, add, 0);
var add2 = curry(map, curry(add, 2));
var max = curry(foldr, Math.max, -Infinity);
var min = curry(foldr, Math.min, Infinity);
var biggerThan2 = curry(gt, 2);
console.log(sum([1, 2, 3, 4, 5, 6]));
console.log(add2([1, 2, 3, 4, 5, 6]));
console.log(filter(biggerThan2,[1, 2, 3, 4, 5, 6]));
console.log(append([1,2,3,4], [4,5,6,7]));
console.log(zip([1,2,3,4], [4,5,6,7]));
console.log(zipWith(add, [1,2,3,4], [4,5,6,7]));
console.log('max', max([1,2,3,4,5, 3]));
console.log('min', min([3]));
console.log(zipWith(Math.max, [1,2,3,4], [4,3,2,1]));
console.log(filter(curry(gt, 5), [1,2,3]));
console.log(quicksort([4,2,5,7,2,7,9,1,2,3]));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment