Created
October 2, 2017 23:55
-
-
Save suissa/d4d5ee092efc45a93b69d3d450971476 to your computer and use it in GitHub Desktop.
Gerenciando estruturas infinitas com Streams - Prog. Funcional de verdade com JS
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
// A definição de um stream se dá inicio com o uso do construtor [Stream] | |
// que recebe como único parâmento uma fonte que é o gerador. | |
// Por meio de técnicas compositivas fluídas é que se define uma cadeia | |
// de composição funcional. As operações de composição são [map] | |
// [reduce] e [filter], versão unitária das funções sobre vetores | |
// e [skip] e [take] que permite saltar ou recoletar n elementos | |
// que passam pela cadeia de composição. | |
// Fonts: | |
// https://sites.ualberta.ca/~jhoover/325/CourseNotes/section/Streams.htm | |
// http://blog.jeremyfairbank.com/javascript/functional-javascript-streams-2/ | |
(function (/* Stream */) { | |
var map = function (fn) { | |
return function () { | |
return fn.apply (null, arguments); | |
}; | |
}; | |
var reduce = function (fn, b) { | |
var ac = b; | |
return function () { | |
var args = [].slice.call (arguments); | |
ac = fn.apply (null, [ac].concat (args)); | |
return ac; | |
}; | |
}; | |
var filter = function (fn) { | |
return function () { | |
var out = fn.apply (null, arguments); | |
if (out) return arguments [0]; | |
}; | |
}; | |
var take = function (n) { | |
var v = []; | |
return function (x) { | |
v.push (x); | |
if (v.length > n) { | |
var w = v.concat ([]); | |
v = []; | |
return w; | |
} | |
}; | |
}; | |
var skip = function (n) { | |
var i = 0; | |
return function (x) { | |
i++; | |
if (i > n) return x; | |
}; | |
}; | |
var fluent = function (hn) { | |
var cb = hn || function () {}; | |
return function (fn) { | |
return function () { | |
cb (fn.apply (null, arguments)); | |
return this; | |
}; | |
}; | |
}; | |
var sequenceBreakWith = function (fns) { | |
return function (data) { | |
return fns.reduce (function (ac, fn) { | |
return ac === void 0 ? void 0 : fn (ac); | |
}, data()); | |
}; | |
}; | |
var Stream = function (source) { | |
var fns = []; | |
var define = fluent (function (fn) { | |
fns.push (fn); | |
}); | |
var next = function (fns, data) { | |
var result = sequenceBreakWith (fns)(data); | |
return result !== void 0 ? result : next (fns, data); | |
}; | |
return { | |
map : define (map), | |
filter : define (filter), | |
reduce : define (reduce), | |
take : define (take), | |
skip : define (skip), | |
end : function () { | |
return { | |
next: function () { | |
return next (fns, source); | |
} | |
}; | |
} | |
}; | |
}; | |
(function (/* Evens */) { | |
var inc = function (x) { return x + 1; }; | |
var evn = function (x) { return x % 2 === 0; }; | |
var source = (function (fn, b) { | |
var c = b; | |
return function () { | |
return (c = fn (c)); | |
}; | |
})(inc, 0); | |
var evens = Stream (source) | |
.skip (10) | |
.map (inc) | |
.filter (evn) | |
.take (5) | |
.end (); | |
console.log ( | |
evens.next (), // [ 12, 14, 16, 18, 20, 22 ] | |
evens.next (), // [ 24, 26, 28, 30, 32, 34 ] | |
evens.next () // [ 36, 38, 40, 42, 44, 46 ] | |
); | |
})(); | |
(function (/* Primes */) { | |
var inc = function (x) { return x + 1; }; | |
var prime = function (x) { | |
return (function primeAux (x, d) { | |
return d > Math.sqrt (x) ? true : | |
x % d === 0 ? false : | |
primeAux (x, d+1); | |
})(x, 2); | |
}; | |
var source = (function (fn, b) { | |
var c = b; | |
return function () { | |
return (c = fn (c)); | |
}; | |
})(inc, 0); | |
var primes = Stream (source) | |
.skip (2) | |
.map (inc) | |
.filter (prime) | |
.take (10) | |
.end (); | |
console.log ( | |
primes.next (), // [ 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41 ] | |
primes.next (), // [ 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89 ] | |
primes.next () // [ 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149 ] | |
); | |
})(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment