Skip to content

Instantly share code, notes, and snippets.

@briancavalier
Created June 1, 2016 22:50

Revisions

  1. briancavalier created this gist Jun 1, 2016.
    90 changes: 90 additions & 0 deletions stream.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,90 @@
    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)
    }