Skip to content

Instantly share code, notes, and snippets.

@briancavalier
Created June 1, 2016 22:50
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 briancavalier/039afcd566172007999d7cda524b73d6 to your computer and use it in GitHub Desktop.
Save briancavalier/039afcd566172007999d7cda524b73d6 to your computer and use it in GitHub Desktop.
Fun with generators as infinite (synchronous) streams
function * empty() {}
function * cons (a, stream) {
yield a
yield * stream
}
function * concat (xs, ys) {
yield * xs
yield * ys
}
function * map (f, stream) {
for(const x of stream) {
yield f(x)
}
}
function * filter (p, stream) {
for(const x of stream) {
if(p(x)) {
yield x
}
}
}
function * take (n, stream) {
for(let x of stream) {
if(n-- === 0) {
return
}
yield x
}
}
function * skip (n, stream) {
for (let x of stream) {
if(--n === 0) {
break
}
}
yield * stream
}
function * ap (fs, xs) {
yield * zipWith(apply, fs, xs)
}
const apply = (f, x) => f(x)
function * chain (f, stream) {
for(let x of stream) {
yield * f(x)
}
}
function * zipWith (f, xs, ys) {
let x = xs.next()
let y = ys.next()
while(!x.done && !y.done) {
yield f(x.value, y.value)
x = xs.next()
y = ys.next()
}
}
function * iterate (f, a) {
yield a
for(;;) {
a = f(a)
yield a
}
}
function * unfold (f, a) {
let [x, y] = f(a)
for(;;) {
yield x
[x, y] = f(y)
}
}
function * integers () {
yield * iterate(x => x + 1, 0)
}
const stream = chain(x => take(3, integers()), take(10, integers()))
for(const y of stream) {
console.log(y)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment