123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576 |
- "use strict";
- module.metadata = {
- "stability": "experimental"
- };
- const { complement, flip, identity } = require("../lang/functional");
- const { iteratorSymbol } = require("../util/iteration");
- const { isArray, isArguments, isMap, isSet,
- isString, isBoolean, isNumber } = require("../lang/type");
- const Sequence = function Sequence(iterator) {
- if (iterator.isGenerator && iterator.isGenerator())
- this[iteratorSymbol] = iterator;
- else
- throw TypeError("Expected generator argument");
- };
- exports.Sequence = Sequence;
- const polymorphic = dispatch => x =>
- x === null ? dispatch.null(null) :
- x === void(0) ? dispatch.void(void(0)) :
- isArray(x) ? (dispatch.array || dispatch.indexed)(x) :
- isString(x) ? (dispatch.string || dispatch.indexed)(x) :
- isArguments(x) ? (dispatch.arguments || dispatch.indexed)(x) :
- isMap(x) ? dispatch.map(x) :
- isSet(x) ? dispatch.set(x) :
- isNumber(x) ? dispatch.number(x) :
- isBoolean(x) ? dispatch.boolean(x) :
- dispatch.default(x);
- const nogen = function*() {};
- const empty = () => new Sequence(nogen);
- exports.empty = empty;
- const seq = polymorphic({
- null: empty,
- void: empty,
- array: identity,
- string: identity,
- arguments: identity,
- map: identity,
- set: identity,
- default: x => x instanceof Sequence ? x : new Sequence(x)
- });
- exports.seq = seq;
- const string = (...etc) => "".concat(...etc);
- exports.string = string;
- const object = (...pairs) => {
- let result = {};
- for (let [key, value] of pairs)
- result[key] = value;
- return result;
- };
- exports.object = object;
- const fromEnumerator = getEnumerator => seq(function* () {
- const enumerator = getEnumerator();
- while (enumerator.hasMoreElements())
- yield enumerator.getNext();
- });
- exports.fromEnumerator = fromEnumerator;
- const pairs = polymorphic({
- null: empty,
- void: empty,
- map: identity,
- indexed: indexed => seq(function* () {
- const count = indexed.length;
- let index = 0;
- while (index < count) {
- yield [index, indexed[index]];
- index = index + 1;
- }
- }),
- default: object => seq(function* () {
- for (let key of Object.keys(object))
- yield [key, object[key]];
- })
- });
- exports.pairs = pairs;
- const keys = polymorphic({
- null: empty,
- void: empty,
- indexed: indexed => seq(function* () {
- const count = indexed.length;
- let index = 0;
- while (index < count) {
- yield index;
- index = index + 1;
- }
- }),
- map: map => seq(function* () {
- for (let [key, _] of map)
- yield key;
- }),
- default: object => seq(function* () {
- for (let key of Object.keys(object))
- yield key;
- })
- });
- exports.keys = keys;
- const values = polymorphic({
- null: empty,
- void: empty,
- set: identity,
- indexed: indexed => seq(function* () {
- const count = indexed.length;
- let index = 0;
- while (index < count) {
- yield indexed[index];
- index = index + 1;
- }
- }),
- map: map => seq(function* () {
- for (let [_, value] of map) yield value;
- }),
- default: object => seq(function* () {
- for (let key of Object.keys(object)) yield object[key];
- })
- });
- exports.values = values;
- const iterate = (f, x) => seq(function* () {
- let state = x;
- while (true) {
- yield state;
- state = f(state);
- }
- });
- exports.iterate = iterate;
- const filter = (p, sequence) => seq(function* () {
- if (sequence !== null && sequence !== void(0)) {
- for (let item of sequence) {
- if (p(item))
- yield item;
- }
- }
- });
- exports.filter = filter;
- const map = (f, ...sequences) => seq(function* () {
- const count = sequences.length;
-
- if (count === 1) {
- let [sequence] = sequences;
- if (sequence !== null && sequence !== void(0)) {
- for (let item of sequence)
- yield f(item);
- }
- }
- else {
-
-
- let args = [];
-
- let inputs = [];
- let index = 0;
- while (index < count) {
- inputs[index] = sequences[index][iteratorSymbol]();
- index = index + 1;
- }
-
-
-
- let done = false;
- while (!done) {
- let index = 0;
- let value = void(0);
- while (index < count && !done) {
- ({ done, value }) = inputs[index].next();
-
- if (!done) {
- args[index] = value;
- index = index + 1;
- }
- }
-
-
- if (!done)
- yield f(...args);
- }
- }
- });
- exports.map = map;
- const reductions = (...params) => {
- const count = params.length;
- let hasInitial = false;
- let f, initial, source;
- if (count === 2) {
- ([f, source]) = params;
- }
- else if (count === 3) {
- ([f, initial, source]) = params;
- hasInitial = true;
- }
- else {
- throw Error("Invoked with wrong number of arguments: " + count);
- }
- const sequence = seq(source);
- return seq(function* () {
- let started = hasInitial;
- let result = void(0);
-
- if (hasInitial)
- yield (result = initial);
-
- for (let item of sequence) {
-
-
- if (!started) {
- started = true;
- yield (result = item);
- }
-
- else {
- yield (result = f(result, item));
- }
- }
-
-
- if (!started)
- yield f();
- });
- };
- exports.reductions = reductions;
- const reduce = (...args) => {
- const xs = reductions(...args);
- let x;
- for (x of xs) void(0);
- return x;
- };
- exports.reduce = reduce;
- const each = (f, sequence) => {
- for (let x of seq(sequence)) void(f(x));
- };
- exports.each = each;
- const inc = x => x + 1;
- const count = polymorphic({
- null: _ => 0,
- void: _ => 0,
- indexed: indexed => indexed.length,
- map: map => map.size,
- set: set => set.size,
- default: xs => reduce(inc, 0, xs)
- });
- exports.count = count;
- // Returns `true` if sequence has no items.
- // Implements clojure empty?:
- // http://clojuredocs.org/clojure_core/clojure.core/empty_q
- const isEmpty = sequence => {
-
- if (sequence === null || sequence === void(0))
- return true;
-
- for (let _ of sequence)
- return false;
-
-
- return true;
- };
- exports.isEmpty = isEmpty;
- const and = (a, b) => a && b;
- const isEvery = (p, sequence) => {
- if (sequence !== null && sequence !== void(0)) {
- for (let item of sequence) {
- if (!p(item))
- return false;
- }
- }
- return true;
- };
- exports.isEvery = isEvery;
- const some = (p, sequence) => {
- if (sequence !== null && sequence !== void(0)) {
- for (let item of sequence) {
- if (p(item))
- return true;
- }
- }
- return null;
- };
- exports.some = some;
- const take = (n, sequence) => n <= 0 ? empty() : seq(function* () {
- let count = n;
- for (let item of sequence) {
- yield item;
- count = count - 1;
- if (count === 0) break;
- }
- });
- exports.take = take;
- const takeWhile = (p, sequence) => seq(function* () {
- for (let item of sequence) {
- if (!p(item))
- break;
- yield item;
- }
- });
- exports.takeWhile = takeWhile;
- const drop = (n, sequence) => seq(function* () {
- if (sequence !== null && sequence !== void(0)) {
- let count = n;
- for (let item of sequence) {
- if (count > 0)
- count = count - 1;
- else
- yield item;
- }
- }
- });
- exports.drop = drop;
- const dropWhile = (p, sequence) => seq(function* () {
- let keep = false;
- for (let item of sequence) {
- keep = keep || !p(item);
- if (keep) yield item;
- }
- });
- exports.dropWhile = dropWhile;
- const concat = (...sequences) => seq(function* () {
- for (let sequence of sequences)
- for (let item of sequence)
- yield item;
- });
- exports.concat = concat;
- const first = sequence => {
- if (sequence !== null && sequence !== void(0)) {
- for (let item of sequence)
- return item;
- }
- return null;
- };
- exports.first = first;
- const rest = sequence => drop(1, sequence);
- exports.rest = rest;
- const nth = (xs, n, notFound) => {
- if (n >= 0) {
- if (isArray(xs) || isArguments(xs) || isString(xs)) {
- return n < xs.length ? xs[n] : notFound;
- }
- else if (xs !== null && xs !== void(0)) {
- let count = n;
- for (let x of xs) {
- if (count <= 0)
- return x;
- count = count - 1;
- }
- }
- }
- return notFound;
- };
- exports.nth = nth;
- const last = polymorphic({
- null: _ => null,
- void: _ => null,
- indexed: indexed => indexed[indexed.length - 1],
- map: xs => reduce((_, x) => x, xs),
- set: xs => reduce((_, x) => x, xs),
- default: xs => reduce((_, x) => x, xs)
- });
- exports.last = last;
- const dropLast = flip((xs, n=1) => seq(function* () {
- let ys = [];
- for (let x of xs) {
- ys.push(x);
- if (ys.length > n)
- yield ys.shift();
- }
- }));
- exports.dropLast = dropLast;
- const distinct = sequence => seq(function* () {
- let items = new Set();
- for (let item of sequence) {
- if (!items.has(item)) {
- items.add(item);
- yield item;
- }
- }
- });
- exports.distinct = distinct;
- const remove = (p, xs) => filter(complement(p), xs);
- exports.remove = remove;
- const mapcat = (f, sequence) => seq(function* () {
- const sequences = map(f, sequence);
- for (let sequence of sequences)
- for (let item of sequence)
- yield item;
- });
- exports.mapcat = mapcat;
|