• Jump To … +
    Either.js List.js Maybe.js Set.js Stream.js Thunk.js Tuple.js boolean.js char.js base.js extra.js fold.js map.js zipWith.js collection.js control.js curried.js eq.js floating.js fractional.js function.js integral.js match.js num.js numeric.js object.js ord.js realfrac.js register.js string.js type.js nodash.js
  • Stream.js

  • ¶
    /* vim: set et sw=2 ts=2: */
    'use strict';
    
    module.exports = [ 'Thunk', 'List', 'idf', 'tuple', 'typeOf', 'freeze', 'error',
      function (Thunk, List, idf, tuple, typeOf, freeze, error) {
    
      var Nodash = this;
    
      function Stream(generator) {
        if (!(this instanceof Stream)) {
          return new Stream(generator);
        }
        var thunk = new Thunk(generator);
        var self = this;
        this.head = function () {
          var value = thunk.get().fst();
          self.head = idf(value);
          return value;
        };
        this.tail = function () {
          var value = thunk.get().snd();
          switch (typeOf(value)) {
            case 'list':
            case 'stream':
              break;
            case 'function':
              value = new Stream(value);
              break;
            default:
              error(TypeError);
          }
          self.tail = idf(value);
          return value;
        };
      }
      Stream.__type = 'stream';
      Stream.prototype = new List();
      Stream.prototype.constructor = Stream;
      Stream.prototype.toString = function () {
        return '[object Stream head=' + this.head() + ']';
      };
    
      freeze(Stream);
    
      return {
    
        'Stream stream': Stream,
    
        'lazy arrayToList': function (val) {
          if (Nodash.isFunction(val)) {
            return new Thunk(val);
          }
          function generator(i) {
            if (i < val.length) {
              return new List(val[i], new Thunk(function () {
                return generator(i + 1);
              }));
            }
            return Nodash.emptyList();
          }
          return generator(0);
        },
    
        each: function (f, xs) {
          if (Nodash.is(List, xs)) {
            while (!xs.isEmpty()) {
              f(xs.head());
              xs = xs.tail();
            }
          } else if (Nodash.isArray(xs) || Nodash.isString(xs)) {
            for (var i = 0; i < xs.length; i++) {
              f(xs[i], i);
            }
          } else if (Nodash.isObject(xs)) {
            var ks = Object.keys(xs);
            for (var j = 0; j < ks.length; j += 1) {
              f(xs[ks[j]], ks[j]);
            }
          }
        },
    
        repeat: function (x) {
          function generator() {
            return tuple(x, generator);
          }
          return new Stream(generator);
        },
    
        iterate: function (f, seed) {
          function generator(seed) {
            return function () {
              var newSeed = f(seed);
              return tuple(seed, generator(newSeed));
            };
          }
          return new Stream(generator(seed));
        },
    
        cycle: function (xs) {
          if (Nodash.isArray(xs)) {
            xs = Nodash.lazy(xs);
          }
          function generator(ys) {
            if (ys.isEmpty()) {
              ys = xs;
            }
            return function () {
              return tuple(ys.head(), generator(ys.tail()));
            };
          }
          return new Stream(generator(xs));
        }
    
      };
    }];