Skip to content

Instantly share code, notes, and snippets.

@mmazer
Created January 28, 2016 15:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmazer/4b48f179465f337fa489 to your computer and use it in GitHub Desktop.
Save mmazer/4b48f179465f337fa489 to your computer and use it in GitHub Desktop.
Transducers in JavaScript
function compose(f, g) {
if (arguments.length === 2) {
return function() {
return f(g.apply(null, arguments));
};
}
var args = [];
for (var i = 0, len = arguments.length; i < len; i++) {
args[i] = arguments[i];
}
return function() {
var i = args.length - 1;
var result = args[i].apply(this, arguments);
while (i--) {
result = args[i].call(this, result);
}
return result;
};
}
function map(f) {
return function(reduce) {
return function(acc, x) {
return reduce(acc, f(x));
};
};
}
function filter(p) {
return function(reduce) {
return function(acc, x) {
console.log('filter=>' + x + ' ' + p(x));
return p(x) ? reduce(acc, x) : acc;
};
};
}
function collect(xs, x) {
xs.push(x);
return xs;
}
function transduce(reducer, xs, val) {
var res = val || [];
return xs.reduce(reducer, res);
}
var even = function(x) {
return x % 2 === 0;
};
var gt = function(x) {
return function(v) {
return v > x;
};
};
function multi(m) {
return function(x) {
return x * m;
};
}
var filterEven = filter(even);
var mapMulti = map(multi(10));
var filterLessThan40 = filter(gt(40));
var filterMap = compose(filterEven, mapMulti, filterLessThan40)(collect);
var mapFilter = compose(map(multi(10)), filter(even))(collect);
var chained = filter(even)(map(multi(10))(collect));
var acc = [];
console.log("filterMap reducer");
var result = transduce(filterMap, xs, acc);
console.log(result);
console.log(acc === result);
console.log("mapFilter reducer");
acc = [];
result = transduce(mapFilter, xs, acc);
console.log(result);
console.log(acc === result);
console.log("chained reducer");
acc = [];
result = transduce(chained, xs, acc);
console.log(result);
console.log(acc === result);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment