Last active
December 18, 2015 04:08
-
-
Save fogus/5722992 to your computer and use it in GitHub Desktop.
This file contains 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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | |
"http://www.w3.org/TR/html4/loose.dtd"> | |
<html> | |
<head> | |
<title>a sketch</title> | |
<script type="text/javascript" src="undermine.js"></script> | |
</head> | |
<body> | |
<center> | |
open the js console and play<br> | |
<a href="http://www.functionaljavascript.com">more about these ideas</a> | |
</center> | |
</body> | |
</html> |
This file contains 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
var exists = function(x) { return x != null; }; | |
var truthy = function(x) { return (x !== false) && exists(x); }; | |
var _filter = function(fun) { | |
return function(coll) { | |
var results = []; | |
if (coll == null) return results; | |
coll.forEach(function(value, index, list) { | |
if (truthy(fun.call(null, value))) results.push(value); | |
}); | |
return results; | |
}; | |
}; | |
function filter(fun) { | |
var coll = arguments[1]; | |
if (exists(coll)) return _filter(fun)(coll); | |
return _filter(fun); | |
} | |
var _map = function(fun) { | |
return function(coll) { | |
var results = []; | |
if (coll == null) return results; | |
coll.forEach(function(value, index, list) { | |
results.push(fun.call(null, value)); | |
}); | |
return results; | |
}; | |
}; | |
function map(fun) { | |
var coll = arguments[1]; | |
if (exists(coll)) return _map(fun)(coll); | |
return _map(fun); | |
} | |
function double(n) { return 2*n; } | |
/* | |
map(double, [1,2,3]) | |
//=> [1, 4, 9] | |
*/ | |
var doubleAll = map(double); | |
/* | |
doubleAll([1,2,3]); | |
//=> [1, 4, 9] | |
*/ | |
function greaterThan(l, r) { | |
return l > r; | |
} | |
function schonfinkel(fun) { | |
return function(first) { | |
return function(last) { | |
return fun(first, last); | |
}; | |
}; | |
}; | |
function flip(fun) { | |
return function() { | |
return fun.call(null, arguments[1], arguments[0]); | |
}; | |
} | |
var gt = schonfinkel(flip(greaterThan)); | |
/* | |
gt(5) | |
//=> function(last) { ... } | |
gt(5)(10000000); | |
//=> true | |
gt(5)(1); | |
//=> false | |
*/ | |
var _reduce = function(fun, seed, coll) { | |
var acc = seed; | |
coll.forEach(function(value) { | |
acc = fun.call(null, acc, value); | |
}); | |
return acc; | |
}; | |
function reduce(fun) { | |
var count = arguments.length; | |
var seed = arguments[1]; | |
var coll = arguments[2]; | |
var result; | |
switch(count) { | |
case 1: | |
result = schonfinkel(_reduce.bind(null, fun)); | |
break; | |
case 2: | |
result = _reduce.bind(null, fun, seed); | |
break; | |
case 3: | |
result = _reduce(fun, seed, coll); | |
break; | |
} | |
return result; | |
} | |
function sum(x,y) { return x + y; } | |
/* | |
reduce(sum, 0, [1,2,3,4,5]); | |
//=> 15 | |
*/ | |
var summate = reduce(sum, 0); | |
/* | |
summate([1,2,3,4,5]); | |
//=> 15 | |
*/ | |
var pipeline = function(/*, funs */){ | |
var funs = Array.prototype.slice.call(arguments); | |
return function(seed) { | |
return reduce(function(l,r) { return r(l); }, | |
seed, | |
funs); | |
}; | |
}; | |
/* | |
pipeline(double)(5); | |
//=> 10 | |
*/ | |
var tasks = pipeline( | |
map(double) | |
, filter(gt(5)) | |
); | |
/* | |
tasks([1,2,3,4,5]); | |
//=> [6,8,10] | |
*/ | |
var moreTasks = pipeline( | |
tasks | |
, reduce(function(x,y) { return x*y }, 1) | |
); | |
/* | |
moreTasks([1,2,3,4,5]); | |
//=> 480 | |
*/ | |
// more ideas like this at http://www.functionaljavascript.com/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment