Skip to content

Instantly share code, notes, and snippets.

@kl0tl
Last active August 29, 2015 14:06
Show Gist options
  • Save kl0tl/fcf858a0cf84c7bd5393 to your computer and use it in GitHub Desktop.
Save kl0tl/fcf858a0cf84c7bd5393 to your computer and use it in GitHub Desktop.
Transducers are awesome
var foldr = Function.prototype.call.bind(Array.prototype.reduceRight);
var source = [9, 8, 7];
var pipeline = compose(filter(odd), map(add(1)));
var pusher = {
step: function (arr, value) { arr.push(value); return arr; },
result: identity
};
console.log(transduce(pipeline, pusher, [], source));
var adder = {
step: function (a, b) { return a + b },
result: identity
};
console.log(transduce(pipeline, adder, 0, source));
function odd(value) {
return value % 2;
}
function add(x) {
return function (value) {
return value + x;
};
}
function identity(value) {
return value;
}
function compose() {
var transducers = arguments;
return function (reducer) {
return foldr(transducers, function (xf, transducer) {
return transducer(xf);
}, reducer);
};
}
function transduce(transducer, reducer, init, coll) {
return reduce(transducer(reducer), init, coll);
}
function reduce(xf, init, coll) {
return xf.result(coll.reduce(xf.step, init));
}
function map(mapper) {
return function (xf) {
return {
init: function () {
return xf.init();
},
step: function (value, item) {
return xf.step(value, mapper(item));
},
result: function (value) {
return xf.result(value);
}
};
};
}
function filter(predicate) {
return function (xf) {
return {
init: function () {
return xf.init();
},
step: function (value, item) {
return predicate(item) ? xf.step(value, item) : value;
},
result: function (value) {
return xf.result(value);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment