Run the following code against Ramda.
// Simple predicate to test whether a number is even
var even = function(n) {return (n % 2) === 0;};
// Generates an infinite list of Fibonacci numbers
var fibsgen = generator(
[0, 1],
function(p) {return p[0];},
function(p) {return [p[1], p[0] + p[1]];}
); // generator: [0, 1, 1, 2, 3, 5, 8, ... ]
// Extracts the first 20 elements of that list
var fibs20 = fibsgen.take(20); // plain list: [0, 1, 1, 2, 3, 5, 8, ... 4181]
All these techniques work well against both the infinite list and the finite one to get the first 5 even Fibonacci numbers:
take(5, filter(even, fibsgen)); //=> [0, 2, 8, 34, 144]
take(5, filter(even, fibs20)); //=> [0, 2, 8, 34, 144]
pipe(filter(even), take(5))(fibsgen); //=> [0, 2, 8, 34, 144]
pipe(filter(even), take(5))(fibs20); //=> [0, 2, 8, 34, 144]
compose(take(5), filter(even))(fibsgen); //=> [0, 2, 8, 34, 144]
compose(take(5), filter(even))(fibs20); //=> [0, 2, 8, 34, 144]
But the following technique only works agains the generator. We don't try to wrap Arrays with all the list functions from Ramda, so we can't usually chain methods in this fluent style:
fibsgen
.filter(even)
.take(5); //=> [0, 2, 8, 34, 144]
But there are clearly times when this is the sort of interface desired, even for
plain list implementations But a technique from Hugh Jackson
can get us reasonably close. Just add tap
to Object.prototype
like so:
Object.prototype.tap = function (fn){ return fn(this.valueOf());};
Then you can use it like this:
fibs20
.tap(filter(even))
.tap(take(5)); //=> [0, 2, 8, 34, 144]
His article goes further, and describes how to create a version that allows for
additional arguments to be passed through. He discusses the reasons people don't
like to extend Object.prototype
and makes a case for this being an exception;
his production implementation is more of a mixin than a simple extension of
Object.prototype
, but still to be widely useful, you'd probably have to apply
it to that prototype, so it's not clear how much help that is, but at least he's
taking the objections seriously.
I feel I should be horrified by this. I'm more than a little uncomfortable to discover that I'm not horrified in the least, just intrigued!