UNPKG

@chris5855/scats

Version:

A comprehensive TypeScript library bringing Scala's powerful functional programming paradigms to JavaScript/TypeScript, featuring immutable collections, monads, pattern matching, and more

2,261 lines (2,254 loc) 111 kB
// src/Option.ts var SomeImpl = class { constructor(value2) { this.value = value2; if (value2 === null || value2 === void 0) { throw new Error("Cannot create Some with null or undefined value"); } } get isSome() { return true; } get isNone() { return false; } get() { return this.value; } getOrElse(_defaultValue) { return this.value; } getOrCall(_f) { return this.value; } getOrThrow(_error) { return this.value; } map(f) { return Some(f(this.value)); } mapOr(_defaultValue, f) { return Some(f(this.value)); } flatMap(f) { return f(this.value); } orElse(_alternative) { return this; } orCall(_f) { return this; } filter(predicate) { return predicate(this.value) ? this : None; } forEach(f) { f(this.value); } toArray() { return [this.value]; } toEither(_left) { return Right(this.value); } match(patterns) { return patterns.Some(this.value); } toString() { return `Some(${this.value})`; } }; var NoneImpl = class { get isSome() { return false; } get isNone() { return true; } get() { throw new Error("Cannot get value from None"); } getOrElse(defaultValue) { return defaultValue; } getOrCall(f) { return f(); } getOrThrow(error) { throw error; } map(_f) { return this; } mapOr(defaultValue, _f) { return Some(defaultValue); } flatMap(_f) { return this; } orElse(alternative) { return alternative; } orCall(f) { return f(); } filter(_predicate) { return this; } forEach(_f) { } toArray() { return []; } toEither(left) { return Left(left); } match(patterns) { return patterns.None(); } toString() { return "None"; } }; var None = new NoneImpl(); function Some(value2) { if (value2 === null || value2 === void 0) { return None; } return new SomeImpl(value2); } var Option; ((Option10) => { function fromNullable(value2) { return value2 === null || value2 === void 0 ? None : Some(value2); } Option10.fromNullable = fromNullable; function tryCatch(f) { try { return Some(f()); } catch (e) { return None; } } Option10.tryCatch = tryCatch; function firstSome(...options) { for (const option of options) { if (option.isSome) return option; } return None; } Option10.firstSome = firstSome; function sequence(options) { const values = []; for (const option of options) { if (option.isNone) return None; values.push(option.get()); } return Some(values); } Option10.sequence = sequence; function traverse(values, f) { return sequence(values.map(f)); } Option10.traverse = traverse; })(Option || (Option = {})); function Left(left) { return { isLeft: true, isRight: false, get: () => { throw new Error("Cannot get value from Left"); }, getLeft: () => left }; } function Right(right) { return { isLeft: false, isRight: true, get: () => right, getLeft: () => { throw new Error("Cannot get left from Right"); } }; } // src/Either.ts var LeftImpl = class { constructor(value2) { this.value = value2; if (value2 === null || value2 === void 0) { throw new Error("Cannot create Left with null or undefined value"); } } get isLeft() { return true; } get isRight() { return false; } get() { throw new Error("Cannot get Right value from Left"); } getLeft() { return this.value; } getOrElse(defaultValue) { return defaultValue; } getOrCall(f) { return f(this.value); } getOrThrow(error) { throw error; } map(_f) { return this; } mapLeft(f) { return Left2(f(this.value)); } flatMap(_f) { return this; } orElse(alternative) { return alternative; } orCall(f) { return f(this.value); } fold(onLeft, _onRight) { return onLeft(this.value); } forEach(_f) { } forEachLeft(f) { f(this.value); } toOption() { return None; } swap() { return Right2(this.value); } match(patterns) { return patterns.Left(this.value); } toString() { return `Left(${this.value})`; } }; var RightImpl = class { constructor(value2) { this.value = value2; if (value2 === null || value2 === void 0) { throw new Error("Cannot create Right with null or undefined value"); } } get isLeft() { return false; } get isRight() { return true; } get() { return this.value; } getLeft() { throw new Error("Cannot get Left value from Right"); } getOrElse(_defaultValue) { return this.value; } getOrCall(_f) { return this.value; } getOrThrow(_error) { return this.value; } map(f) { return Right2(f(this.value)); } mapLeft(_f) { return this; } flatMap(f) { return f(this.value); } orElse(_alternative) { return this; } orCall(_f) { return this; } fold(_onLeft, onRight) { return onRight(this.value); } forEach(f) { f(this.value); } forEachLeft(_f) { } toOption() { return Some(this.value); } swap() { return Left2(this.value); } match(patterns) { return patterns.Right(this.value); } toString() { return `Right(${this.value})`; } }; function Left2(left) { if (left === null || left === void 0) { throw new Error("Cannot create Left with null or undefined value"); } return new LeftImpl(left); } function Right2(right) { if (right === null || right === void 0) { throw new Error("Cannot create Right with null or undefined value"); } return new RightImpl(right); } var Either; ((Either4) => { function tryCatch(f) { try { return Right2(f()); } catch (e) { return Left2(e); } } Either4.tryCatch = tryCatch; function sequence(eithers) { const values = []; for (const either of eithers) { if (either.isLeft) return either; values.push(either.get()); } return Right2(values); } Either4.sequence = sequence; function traverse(values, f) { return sequence(values.map(f)); } Either4.traverse = traverse; })(Either || (Either = {})); // src/Try.ts var SuccessImpl = class _SuccessImpl { constructor(value2) { this.value = value2; } get isSuccess() { return true; } get isFailure() { return false; } get() { return this.value; } getOrElse(_defaultValue) { return this.value; } getError() { throw new Error("Cannot get error from Success"); } failed() { return new FailureImpl(new Error("Success has no failure")); } map(f) { try { return new _SuccessImpl(f(this.value)); } catch (e) { return new FailureImpl(e instanceof Error ? e : new Error(String(e))); } } flatMap(f) { try { return f(this.value); } catch (e) { return new FailureImpl(e instanceof Error ? e : new Error(String(e))); } } recover(_f) { return this; } recoverWith(_f) { return this; } transform(s, _f) { try { return s(this.value); } catch (e) { return new FailureImpl(e instanceof Error ? e : new Error(String(e))); } } toOption() { return Some(this.value); } toEither() { return Right2(this.value); } fold(_onFailure, onSuccess) { return onSuccess(this.value); } match(patterns) { return patterns.Success(this.value); } toString() { return `Success(${this.value})`; } }; var FailureImpl = class _FailureImpl { constructor(error) { this.error = error; } get isSuccess() { return false; } get isFailure() { return true; } get() { throw this.error; } getOrElse(defaultValue) { return defaultValue; } getError() { return this.error; } failed() { return new SuccessImpl(this.error); } map(_f) { return this; } flatMap(_f) { return this; } recover(f) { try { return new SuccessImpl(f(this.error)); } catch (e) { return new _FailureImpl(e instanceof Error ? e : new Error(String(e))); } } recoverWith(f) { try { return f(this.error); } catch (e) { return new _FailureImpl(e instanceof Error ? e : new Error(String(e))); } } transform(_s, f) { try { return f(this.error); } catch (e) { return new _FailureImpl(e instanceof Error ? e : new Error(String(e))); } } toOption() { return None; } toEither() { return Left2(this.error); } fold(onFailure, _onSuccess) { return onFailure(this.error); } match(patterns) { return patterns.Failure(this.error); } toString() { return `Failure(${this.error})`; } }; function Success(value2) { return new SuccessImpl(value2); } function Failure(error) { return new FailureImpl(error); } var Try; ((Try4) => { function of(f) { try { return Success(f()); } catch (e) { return Failure(e instanceof Error ? e : new Error(String(e))); } } Try4.of = of; function sequence(tries) { const values = []; for (const t of tries) { if (t.isFailure) return t; values.push(t.get()); } return Success(values); } Try4.sequence = sequence; function traverse(values, f) { return sequence(values.map(f)); } Try4.traverse = traverse; })(Try || (Try = {})); var TryAsyncImpl = class _TryAsyncImpl { constructor(promise) { this.promise = promise; } map(f) { return new _TryAsyncImpl( this.promise.then(async (result) => { if (result.isFailure) return result; try { const value2 = await f(result.get()); return Success(value2); } catch (e) { return Failure(e instanceof Error ? e : new Error(String(e))); } }) ); } flatMap(f) { return new _TryAsyncImpl( this.promise.then(async (result) => { if (result.isFailure) return result; try { const tryAsync = await f(result.get()); return await tryAsync.toPromise().then(Success).catch( (e) => Failure(e instanceof Error ? e : new Error(String(e))) ); } catch (e) { return Failure(e instanceof Error ? e : new Error(String(e))); } }) ); } recover(f) { return new _TryAsyncImpl( this.promise.then(async (result) => { if (result.isSuccess) return result; try { const value2 = await f(result.getError()); return Success(value2); } catch (e) { return Failure(e instanceof Error ? e : new Error(String(e))); } }) ); } recoverWith(f) { return new _TryAsyncImpl( this.promise.then(async (result) => { if (result.isSuccess) return result; try { const tryAsync = await f(result.getError()); return await tryAsync.toPromise().then( (value2) => Success(value2) ).catch( (e) => Failure(e instanceof Error ? e : new Error(String(e))) ); } catch (e) { return Failure(e instanceof Error ? e : new Error(String(e))); } }) ); } async toPromise() { const result = await this.promise; if (result.isSuccess) { return result.get(); } else { throw result.getError(); } } }; var TryAsync; ((TryAsync2) => { function of(f) { return new TryAsyncImpl( Promise.resolve().then(async () => { try { const value2 = await f(); return Success(value2); } catch (e) { return Failure(e instanceof Error ? e : new Error(String(e))); } }) ); } TryAsync2.of = of; function success(value2) { return new TryAsyncImpl(Promise.resolve(Success(value2))); } TryAsync2.success = success; function failure(error) { return new TryAsyncImpl(Promise.resolve(Failure(error))); } TryAsync2.failure = failure; function fromPromise(promise) { return of(() => promise); } TryAsync2.fromPromise = fromPromise; })(TryAsync || (TryAsync = {})); // src/ExecutionContext.ts var GlobalExecutionContext = class { /** * Executes a task asynchronously. */ execute(task) { setTimeout(task, 0); } /** * Reports a failure to the console. */ reportFailure(cause) { console.error("Execution context failure:", cause); } }; var SynchronousExecutionContext = class { /** * Executes a task immediately in the current thread. */ execute(task) { task(); } /** * Reports a failure to the console. */ reportFailure(cause) { console.error("Execution context failure:", cause); } }; var ExecutionContext = { /** * The global execution context. */ global: new GlobalExecutionContext(), /** * A synchronous execution context for testing. */ synchronous: new SynchronousExecutionContext(), /** * Creates an execution context from a function that executes tasks. */ fromExecutor(executor, reporter = console.error) { return { execute: executor, reportFailure: reporter }; } }; // src/List.ts var EmptyList = class { get isEmpty() { return true; } get size() { return 0; } head() { throw new Error("Cannot get head of empty list"); } tail() { throw new Error("Cannot get tail of empty list"); } headOption() { return None; } tailOption() { return None; } prepend(element) { return new ConsImpl(element, this); } append(element) { return new ConsImpl(element, this); } concat(that) { return that; } map(_f) { return empty(); } flatMap(_f) { return empty(); } filter(_predicate) { return this; } partition(_predicate) { return [this, this]; } exists(_predicate) { return false; } forAll(_predicate) { return true; } foldLeft(initial, _f) { return initial; } foldRight(initial, _f) { return initial; } forEach(_f) { } slice(_start, _end) { return this; } take(_n) { return this; } drop(_n) { return this; } takeWhile(_predicate) { return this; } dropWhile(_predicate) { return this; } get(_index) { throw new Error("Index out of bounds"); } getOption(_index) { return None; } updateAt(_index, _element) { return this; } indexOf(_element) { return -1; } contains(_element) { return false; } distinct() { return this; } reverse() { return this; } sorted(_compareFn) { return this; } toArray() { return []; } toString() { return "List()"; } *[Symbol.iterator]() { } }; var ConsImpl = class _ConsImpl { constructor(_head, _tail) { this._head = _head; this._tail = _tail; } get isEmpty() { return false; } get size() { let size = 1; let current = this._tail; while (!current.isEmpty) { size += 1; current = current.tail(); } return size; } head() { return this._head; } tail() { return this._tail; } headOption() { return Some(this._head); } tailOption() { return Some(this._tail); } prepend(element) { return new _ConsImpl(element, this); } append(element) { return this.concat(List.of(element)); } concat(that) { if (that.isEmpty) return this; let reversed = empty(); let current = this; while (!current.isEmpty) { reversed = reversed.prepend(current.head()); current = current.tail(); } let result = that; current = reversed; while (!current.isEmpty) { result = result.prepend(current.head()); current = current.tail(); } return result; } map(f) { const result = []; let current = this; while (!current.isEmpty) { result.push(f(current.head())); current = current.tail(); } let listResult = empty(); for (let i = result.length - 1; i >= 0; i--) { listResult = listResult.prepend(result[i]); } return listResult; } flatMap(f) { let result = empty(); const elements = []; let current = this; while (!current.isEmpty) { elements.push(f(current.head())); current = current.tail(); } for (let i = elements.length - 1; i >= 0; i--) { result = elements[i].concat(result); } return result; } filter(predicate) { const result = []; let current = this; while (!current.isEmpty) { const head = current.head(); if (predicate(head)) { result.push(head); } current = current.tail(); } let listResult = empty(); for (let i = result.length - 1; i >= 0; i--) { listResult = listResult.prepend(result[i]); } return listResult; } partition(predicate) { const trueResults = []; const falseResults = []; let current = this; while (!current.isEmpty) { const head = current.head(); if (predicate(head)) { trueResults.push(head); } else { falseResults.push(head); } current = current.tail(); } let trueList = empty(); for (let i = trueResults.length - 1; i >= 0; i--) { trueList = trueList.prepend(trueResults[i]); } let falseList = empty(); for (let i = falseResults.length - 1; i >= 0; i--) { falseList = falseList.prepend(falseResults[i]); } return [trueList, falseList]; } exists(predicate) { let current = this; while (!current.isEmpty) { if (predicate(current.head())) { return true; } current = current.tail(); } return false; } forAll(predicate) { let current = this; while (!current.isEmpty) { if (!predicate(current.head())) { return false; } current = current.tail(); } return true; } foldLeft(initial, f) { let result = initial; let current = this; while (!current.isEmpty) { result = f(result, current.head()); current = current.tail(); } return result; } foldRight(initial, f) { const reversed = this.reverse(); return reversed.foldLeft(initial, (acc, a) => f(a, acc)); } forEach(f) { let current = this; while (!current.isEmpty) { f(current.head()); current = current.tail(); } } slice(start, end) { const endIndex = end === void 0 ? this.size : end; return this.take(endIndex).drop(start); } take(n) { if (n <= 0) return empty(); const result = []; let current = this; let count = 0; while (!current.isEmpty && count < n) { result.push(current.head()); current = current.tail(); count += 1; } let listResult = empty(); for (let i = result.length - 1; i >= 0; i--) { listResult = listResult.prepend(result[i]); } return listResult; } drop(n) { if (n <= 0) return this; let current = this; let count = 0; while (!current.isEmpty && count < n) { current = current.tail(); count += 1; } return current; } takeWhile(predicate) { const result = []; let current = this; while (!current.isEmpty) { const head = current.head(); if (!predicate(head)) break; result.push(head); current = current.tail(); } let listResult = empty(); for (let i = result.length - 1; i >= 0; i--) { listResult = listResult.prepend(result[i]); } return listResult; } dropWhile(predicate) { let current = this; while (!current.isEmpty) { if (!predicate(current.head())) { return current; } current = current.tail(); } return empty(); } get(index) { if (index < 0) { throw new Error("Index out of bounds"); } let current = this; let currentIndex = 0; while (!current.isEmpty) { if (currentIndex === index) { return current.head(); } current = current.tail(); currentIndex += 1; } throw new Error("Index out of bounds"); } getOption(index) { if (index < 0) { return None; } let current = this; let currentIndex = 0; while (!current.isEmpty) { if (currentIndex === index) { return Some(current.head()); } current = current.tail(); currentIndex += 1; } return None; } updateAt(index, element) { if (index < 0) { return this; } const result = []; let current = this; let currentIndex = 0; let found = false; while (!current.isEmpty) { if (currentIndex === index) { result.push(element); found = true; } else { result.push(current.head()); } current = current.tail(); currentIndex += 1; } if (!found) { return this; } let listResult = empty(); for (let i = result.length - 1; i >= 0; i--) { listResult = listResult.prepend(result[i]); } return listResult; } indexOf(element) { let current = this; let currentIndex = 0; while (!current.isEmpty) { if (current.head() === element) { return currentIndex; } current = current.tail(); currentIndex += 1; } return -1; } contains(element) { return this.indexOf(element) !== -1; } distinct() { const seen = /* @__PURE__ */ new Set(); const result = []; let current = this; while (!current.isEmpty) { const head = current.head(); if (!seen.has(head)) { seen.add(head); result.push(head); } current = current.tail(); } let listResult = empty(); for (let i = result.length - 1; i >= 0; i--) { listResult = listResult.prepend(result[i]); } return listResult; } reverse() { let result = empty(); let current = this; while (!current.isEmpty) { result = result.prepend(current.head()); current = current.tail(); } return result; } sorted(compareFn) { const array2 = this.toArray(); array2.sort(compareFn); let result = empty(); for (let i = array2.length - 1; i >= 0; i--) { result = result.prepend(array2[i]); } return result; } toArray() { const result = []; let current = this; while (!current.isEmpty) { result.push(current.head()); current = current.tail(); } return result; } toString() { return `List(${this.toArray().join(", ")})`; } *[Symbol.iterator]() { let current = this; while (!current.isEmpty) { yield current.head(); current = current.tail(); } } }; function empty() { return new EmptyList(); } var List; ((List2) => { function of(...elements) { let result = empty3(); for (let i = elements.length - 1; i >= 0; i--) { result = result.prepend(elements[i]); } return result; } List2.of = of; function fromArray(array2) { return of(...array2); } List2.fromArray = fromArray; function fromIterable(iterable) { return fromArray([...iterable]); } List2.fromIterable = fromIterable; function empty3() { return new EmptyList(); } List2.empty = empty3; function fill(n, f) { const array2 = Array(n).fill(null).map((_, i) => f(i)); return fromArray(array2); } List2.fill = fill; function repeat(element, n) { return fill(n, () => element); } List2.repeat = repeat; function range(start, end, step = 1) { if (step === 0) { throw new Error("Step cannot be 0"); } const array2 = []; if (step > 0) { for (let i = start; i < end; i += step) { array2.push(i); } } else { for (let i = start; i > end; i += step) { array2.push(i); } } return fromArray(array2); } List2.range = range; function zip(as, bs) { const result = []; let currA = as; let currB = bs; while (!currA.isEmpty && !currB.isEmpty) { result.push([currA.head(), currB.head()]); currA = currA.tail(); currB = currB.tail(); } return fromArray(result); } List2.zip = zip; function map2(as, bs, f) { return zip(as, bs).map(([a, b]) => f(a, b)); } List2.map2 = map2; })(List || (List = {})); // src/Map.ts var MapImpl = class _MapImpl { constructor(entries) { this._map = new globalThis.Map(entries); } get isEmpty() { return this._map.size === 0; } get size() { return this._map.size; } get keys() { return List.fromIterable(this._map.keys()); } get values() { return List.fromIterable(this._map.values()); } get entries() { return List.fromIterable(this._map.entries()); } get(key) { return this._map.has(key) ? Some(this._map.get(key)) : None; } getOrElse(key, defaultValue) { return this._map.has(key) ? this._map.get(key) : defaultValue; } set(key, value2) { const newMap = new globalThis.Map(this._map); newMap.set(key, value2); return new _MapImpl(newMap); } setAll(entries) { const newMap = new globalThis.Map(this._map); for (const [key, value2] of entries) { newMap.set(key, value2); } return new _MapImpl(newMap); } remove(key) { if (!this._map.has(key)) { return this; } const newMap = new globalThis.Map(this._map); newMap.delete(key); return new _MapImpl(newMap); } removeAll(keys) { const newMap = new globalThis.Map(this._map); for (const key of keys) { newMap.delete(key); } return new _MapImpl(newMap); } update(key, f) { if (!this._map.has(key)) { return this; } const newMap = new globalThis.Map(this._map); newMap.set(key, f(this._map.get(key))); return new _MapImpl(newMap); } updateOrSet(key, f) { const newMap = new globalThis.Map(this._map); const currentValue = this._map.has(key) ? Some(this._map.get(key)) : None; newMap.set(key, f(currentValue)); return new _MapImpl(newMap); } merge(that) { return this.setAll(that.entries.toArray()); } map(f) { const newEntries = []; this._map.forEach((value2, key) => { newEntries.push([key, f(value2, key)]); }); return new _MapImpl(newEntries); } filter(predicate) { const newEntries = []; this._map.forEach((value2, key) => { if (predicate(value2, key)) { newEntries.push([key, value2]); } }); return new _MapImpl(newEntries); } exists(predicate) { for (const [key, value2] of this._map.entries()) { if (predicate(value2, key)) { return true; } } return false; } forAll(predicate) { for (const [key, value2] of this._map.entries()) { if (!predicate(value2, key)) { return false; } } return true; } foldLeft(initial, f) { let result = initial; this._map.forEach((value2, key) => { result = f(result, value2, key); }); return result; } forEach(f) { this._map.forEach((value2, key) => { f(value2, key); }); } has(key) { return this._map.has(key); } toNativeMap() { return new globalThis.Map(this._map); } toString() { if (this.isEmpty) { return "Map()"; } const entries = Array.from(this._map.entries()).map(([key, value2]) => `[${String(key)}, ${String(value2)}]`).join(", "); return `Map(${entries})`; } }; var Map2; ((Map3) => { function of(entries) { return new MapImpl(entries); } Map3.of = of; function fromList(entries) { return of(entries.toArray()); } Map3.fromList = fromList; function fromNativeMap(map) { return of(map.entries()); } Map3.fromNativeMap = fromNativeMap; function empty3() { return new MapImpl(); } Map3.empty = empty3; function fromKeys(keys, f) { return fromList(keys.map((key) => [key, f(key)])); } Map3.fromKeys = fromKeys; function fromValues(values, f) { return fromList(values.map((value2) => [f(value2), value2])); } Map3.fromValues = fromValues; })(Map2 || (Map2 = {})); // src/Set.ts var SetImpl = class _SetImpl { constructor(elements) { this._set = new globalThis.Set(elements); } get isEmpty() { return this._set.size === 0; } get size() { return this._set.size; } get values() { return List.fromIterable(this._set.values()); } contains(element) { return this._set.has(element); } add(element) { if (this._set.has(element)) { return this; } const newSet = new globalThis.Set(this._set); newSet.add(element); return new _SetImpl(newSet); } addAll(elements) { const newSet = new globalThis.Set(this._set); let changed = false; for (const element of elements) { if (!this._set.has(element)) { newSet.add(element); changed = true; } } return changed ? new _SetImpl(newSet) : this; } remove(element) { if (!this._set.has(element)) { return this; } const newSet = new globalThis.Set(this._set); newSet.delete(element); return new _SetImpl(newSet); } removeAll(elements) { const newSet = new globalThis.Set(this._set); let changed = false; for (const element of elements) { if (this._set.has(element)) { newSet.delete(element); changed = true; } } return changed ? new _SetImpl(newSet) : this; } union(that) { if (that.isEmpty) { return this; } if (this.isEmpty) { return that; } return this.addAll(that.toArray()); } intersection(that) { if (this.isEmpty || that.isEmpty) { return empty2(); } const newSet = new globalThis.Set(); for (const element of this._set) { if (that.contains(element)) { newSet.add(element); } } return new _SetImpl(newSet); } difference(that) { if (this.isEmpty) { return empty2(); } if (that.isEmpty) { return this; } return this.removeAll(that.toArray()); } isSubsetOf(that) { if (this.isEmpty) { return true; } if (this.size > that.size) { return false; } return this.forAll((element) => that.contains(element)); } isProperSubsetOf(that) { return this.size < that.size && this.isSubsetOf(that); } isSupersetOf(that) { return that.isSubsetOf(this); } isProperSupersetOf(that) { return that.isProperSubsetOf(this); } map(f) { const newSet = new globalThis.Set(); this._set.forEach((element) => { newSet.add(f(element)); }); return new _SetImpl(newSet); } filter(predicate) { const newSet = new globalThis.Set(); this._set.forEach((element) => { if (predicate(element)) { newSet.add(element); } }); return new _SetImpl(newSet); } exists(predicate) { for (const element of this._set) { if (predicate(element)) { return true; } } return false; } forAll(predicate) { for (const element of this._set) { if (!predicate(element)) { return false; } } return true; } foldLeft(initial, f) { let result = initial; this._set.forEach((element) => { result = f(result, element); }); return result; } forEach(f) { this._set.forEach((element) => { f(element); }); } partition(predicate) { const trueSet = new globalThis.Set(); const falseSet = new globalThis.Set(); this._set.forEach((element) => { if (predicate(element)) { trueSet.add(element); } else { falseSet.add(element); } }); return [new _SetImpl(trueSet), new _SetImpl(falseSet)]; } toNativeSet() { return new globalThis.Set(this._set); } toArray() { return Array.from(this._set); } toString() { if (this.isEmpty) { return "Set()"; } return `Set(${this.toArray().join(", ")})`; } }; function empty2() { return new SetImpl(); } var Set2; ((Set3) => { function of(...elements) { return new SetImpl(elements); } Set3.of = of; function fromIterable(iterable) { return new SetImpl(iterable); } Set3.fromIterable = fromIterable; function fromNativeSet(set) { return new SetImpl(set); } Set3.fromNativeSet = fromNativeSet; function empty3() { return new SetImpl(); } Set3.empty = empty3; })(Set2 || (Set2 = {})); // src/collections/Iterable.ts var AbstractIterable = class { [Symbol.iterator]() { return this.iterator(); } forEach(f) { for (const a of this) { f(a); } } map(f) { return new MappedIterable(this, f); } flatMap(f) { return new FlatMappedIterable(this, f); } collect(f) { return new CollectedIterable(this, f); } concat(other) { return new ConcatenatedIterable(this, other); } filter(p) { return new FilteredIterable(this, p); } filterNot(p) { return this.filter((a) => !p(a)); } withFilter(p) { return this.filter(p); } head() { const iterator = this.iterator(); const result = iterator.next(); if (result.done) { throw new Error("Collection is empty"); } return result.value; } headOption() { const iterator = this.iterator(); const result = iterator.next(); return result.done ? None : Some(result.value); } last() { let last; let hasElements = false; for (const a of this) { last = a; hasElements = true; } if (!hasElements) { throw new Error("Collection is empty"); } return last; } lastOption() { let last; let hasElements = false; for (const a of this) { last = a; hasElements = true; } return hasElements ? Some(last) : None; } find(p) { for (const a of this) { if (p(a)) { return Some(a); } } return None; } tail() { const iterator = this.iterator(); const result = iterator.next(); if (result.done) { throw new Error("Collection is empty"); } return new TailIterable(this); } init() { if (this.isEmpty()) { throw new Error("Collection is empty"); } return new InitIterable(this); } slice(from, to) { return new SlicedIterable(this, from, to); } take(n) { return new TakenIterable(this, n); } drop(n) { return new DroppedIterable(this, n); } takeWhile(p) { return new TakeWhileIterable(this, p); } dropWhile(p) { return new DropWhileIterable(this, p); } takeRight(n) { return new TakeRightIterable(this, n); } dropRight(n) { return new DropRightIterable(this, n); } splitAt(n) { return [this.take(n), this.drop(n)]; } span(p) { return [this.takeWhile(p), this.dropWhile(p)]; } partition(p) { return [this.filter(p), this.filterNot(p)]; } groupBy(f) { const map = new globalThis.Map(); for (const a of this) { const key = f(a); const group = map.get(key) || []; group.push(a); map.set(key, group); } const result = new globalThis.Map(); for (const [key, values] of map.entries()) { result.set(key, new ArrayIterable(values)); } return result; } forall(p) { for (const a of this) { if (!p(a)) { return false; } } return true; } exists(p) { for (const a of this) { if (p(a)) { return true; } } return false; } count(p) { let count = 0; for (const a of this) { if (p(a)) { count++; } } return count; } foldLeft(z, op) { let result = z; for (const a of this) { result = op(result, a); } return result; } foldRight(z, op) { const array2 = this.toArray(); let result = z; for (let i = array2.length - 1; i >= 0; i--) { result = op(array2[i], result); } return result; } reduceLeft(op) { const iterator = this.iterator(); const first = iterator.next(); if (first.done) { throw new Error("Collection is empty"); } let result = first.value; let hasStarted = false; for (const a of this) { if (!hasStarted) { hasStarted = true; continue; } result = op(result, a); } return result; } reduceRight(op) { const array2 = this.toArray(); if (array2.length === 0) { throw new Error("Collection is empty"); } let result = array2[array2.length - 1]; for (let i = array2.length - 2; i >= 0; i--) { result = op(array2[i], result); } return result; } sum() { return this.foldLeft(0, (sum, a) => { if (typeof a !== "number") { throw new Error("Collection contains non-numeric values"); } return sum + a; }); } product() { return this.foldLeft(1, (prod, a) => { if (typeof a !== "number") { throw new Error("Collection contains non-numeric values"); } return prod * a; }); } min() { if (this.isEmpty()) { throw new Error("Collection is empty"); } let min; let first = true; for (const a of this) { if (first || a < min) { min = a; first = false; } } return min; } max() { if (this.isEmpty()) { throw new Error("Collection is empty"); } let max; let first = true; for (const a of this) { if (first || a > max) { max = a; first = false; } } return max; } minOption() { if (this.isEmpty()) { return None; } return Some(this.min()); } maxOption() { if (this.isEmpty()) { return None; } return Some(this.max()); } mkString(start = "", sep = "", end = "") { const elements = this.toArray(); return start + elements.join(sep) + end; } zip(other) { return new ZippedIterable(this, other); } zipAll(other, thisElem, thatElem) { return new ZipAllIterable(this, other, thisElem, thatElem); } zipWithIndex() { return new ZipWithIndexIterable(this); } isEmpty() { const result = this.iterator().next(); return !!result.done; } nonEmpty() { return !this.isEmpty(); } size() { let count = 0; for (const _ of this) { count++; } return count; } knownSize() { return -1; } sizeCompare(other) { const thisSize = this.size(); if (typeof other === "number") { return thisSize - other; } else { const otherSize = other.size(); return thisSize - otherSize; } } grouped(size) { return new GroupedIterator(this, size); } sliding(size) { return new SlidingIterator(this, size); } toArray() { const result = []; for (const a of this) { result.push(a); } return result; } toList() { return List.of(...this.toArray()); } toSet() { return Set2.of(...this.toArray()); } toMap() { const entries = []; for (const a of this) { if (!Array.isArray(a) || a.length !== 2) { throw new Error("Collection does not have pairs as elements"); } entries.push([a[0], a[1]]); } return Map2.of(entries); } }; var MappedIterable = class extends AbstractIterable { constructor(source, f) { super(); this.source = source; this.f = f; } iterator() { const sourceIterator = this.source.iterator(); return { next: () => { const result = sourceIterator.next(); if (result.done) { return { done: true, value: void 0 }; } return { done: false, value: this.f(result.value) }; } }; } }; var FlatMappedIterable = class extends AbstractIterable { constructor(source, f) { super(); this.source = source; this.f = f; } iterator() { const sourceIterator = this.source.iterator(); let currentIterator = null; return { next: () => { while (true) { if (currentIterator === null) { const sourceResult = sourceIterator.next(); if (sourceResult.done) { return { done: true, value: void 0 }; } currentIterator = this.f(sourceResult.value).iterator(); } const result = currentIterator.next(); if (result.done) { currentIterator = null; continue; } return { done: false, value: result.value }; } return { done: true, value: void 0 }; } }; } }; var CollectedIterable = class extends AbstractIterable { constructor(source, f) { super(); this.source = source; this.f = f; } iterator() { const sourceIterator = this.source.iterator(); return { next: () => { while (true) { const sourceResult = sourceIterator.next(); if (sourceResult.done) { return { done: true, value: void 0 }; } const option = this.f(sourceResult.value); if (option.isSome) { return { done: false, value: option.get() }; } } return { done: true, value: void 0 }; } }; } }; var ConcatenatedIterable = class extends AbstractIterable { constructor(first, second) { super(); this.first = first; this.second = second; } iterator() { const firstIterator = this.first.iterator(); const secondIterator = this.second.iterator(); let firstDone = false; return { next: () => { if (!firstDone) { const result2 = firstIterator.next(); if (!result2.done) { return { done: false, value: result2.value }; } firstDone = true; } const result = secondIterator.next(); if (result.done) { return { done: true, value: void 0 }; } return { done: false, value: result.value }; } }; } }; var FilteredIterable = class extends AbstractIterable { constructor(source, p) { super(); this.source = source; this.p = p; } iterator() { const sourceIterator = this.source.iterator(); return { next: () => { while (true) { const result = sourceIterator.next(); if (result.done) { return { done: true, value: void 0 }; } if (this.p(result.value)) { return { done: false, value: result.value }; } } return { done: true, value: void 0 }; } }; } }; var TailIterable = class extends AbstractIterable { constructor(source) { super(); this.source = source; } iterator() { const sourceIterator = this.source.iterator(); const first = sourceIterator.next(); if (first.done) { throw new Error("Collection is empty"); } return { next: () => { const result = sourceIterator.next(); if (result.done) { return { done: true, value: void 0 }; } return { done: false, value: result.value }; } }; } }; var InitIterable = class extends AbstractIterable { constructor(source) { super(); this.source = source; } iterator() { const array2 = this.source.toArray(); if (array2.length === 0) { throw new Error("Collection is empty"); } let index = 0; return { next: () => { if (index >= array2.length - 1) { return { done: true, value: void 0 }; } return { done: false, value: array2[index++] }; } }; } }; var SlicedIterable = class extends AbstractIterable { constructor(source, from, to) { super(); this.source = source; this.from = from; this.to = to; } iterator() { const array2 = this.source.toArray(); const start = Math.max(0, this.from); const end = Math.min(array2.length, this.to); let index = start; return { next: () => { if (index >= end) { return { done: true, value: void 0 }; } return { done: false, value: array2[index++] }; } }; } }; var TakenIterable = class extends AbstractIterable { constructor(source, n) { super(); this.source = source; this.n = n; } iterator() { const sourceIterator = this.source.iterator(); let count = 0; return { next: () => { if (count >= this.n) { return { done: true, value: void 0 }; } const result = sourceIterator.next(); if (result.done) { return { done: true, value: void 0 }; } count++; return { done: false, value: result.value }; } }; } }; var DroppedIterable = class extends AbstractIterable { constructor(source, n) { super(); this.source = source; this.n = n; } iterator() { const sourceIterator = this.source.iterator(); let count = 0; return { next: () => { while (count < this.n) { const result2 = sourceIterator.next(); if (result2.done) { return { done: true, value: void 0 }; } count++; } const result = sourceIterator.next(); if (result.done) { return { done: true, value: void 0 }; } return { done: false, value: result.value }; } }; } }; var TakeWhileIterable = class extends AbstractIterable { constructor(source, p) { super(); this.source = source; this.p = p; } iterator() { const sourceIterator = this.source.iterator(); let done = false; return { next: () => { if (done) { return { done: true, value: void 0 }; } const result = sourceIterator.next(); if (result.done) { done = true; return { done: true, value: void 0 }; } if (!this.p(result.value)) { done = true; return { done: true, value: void 0 }; } return { done: false, value: result.value }; } }; } }; var DropWhileIterable = class extends AbstractIterable { constructor(source, p) { super(); this.source = source; this.p = p; } iterator() { const sourceIterator = this.source.iterator(); let found = false; return { next: () => { if (found) { const result = sourceIterator.next(); if (result.done) { return { done: true, value: void 0 }; } return { done: false, value: result.value }; } while (true) { const result = sourceIterator.next(); if (result.done) { return { done: true, value: void 0 }; } if (!this.p(result.value)) { found = true; return { done: false, value: result.value }; } } return { done: true, value: void 0 }; } }; } }; var TakeRightIterable = class extends AbstractIterable { constructor(source, n) { super(); this.source = source; this.n = n; } iterator() { const array2 = this.source.toArray(); const start = Math.max(0, array2.length - this.n); let index = start; return { next: () => { if (index >= array2.length) { return { done: true, value: void 0 }; } return { done: false, value: array2[index++] }; } }; } }; var DropRightIterable = class extends AbstractIterable { constructor(source, n) { super(); this.source = source; this.n = n; } iterator() { const array2 = this.source.toArray(); const end = Math.max(0, array2.length - this.n); let index = 0; return { next: () => { if (index >= end) { return { done: true, value: void 0 }; } return { done: false, value: array2[index++] }; } }; } }; var ZippedIterable = class extends AbstractIterable { constructor(first, second) { super(); this.first = first; this.second = second; } iterator() { const firstIterator = this.first.iterator(); const secondIterator = this.second.iterator(); return { next: () => { const firstResult = firstIterator.next(); const secondResult = secondIterator.next(); if (firstResult.done || secondResult.done) { return { done: true, value: void 0 }; } return { done: false, value: [firstResult.value, secondResult.value] }; } }; } }; var ZipAllIterable = class extends AbstractIterable { constructor(first, second, thisElem, thatElem) { super(); this.first = first; this.second = second; this.thisElem = thisElem; this.thatElem = thatElem; } iterator() { const firstIterator = this.first.iterator(); const secondIterator = this.second.iterator(); let firstDone = false; let secondDone = false; return { next: () => { const firstResult = firstIterator.next(); const secondResult = secondIterator.next(); if (firstResult.done) { firstDone = true; } if (secondResult.done) { secondDone = true; } if (firstDone && secondDone) { return { done: true, value: void 0 }; } const a = firstDone ? this.thisElem : firstResult.value; const b = secondDone ? this.thatElem : secondResult.value; return { done: false, value: [a, b] }; } }; } }; var ZipWithIndexIterable = class extends AbstractIterable { constructor(source) { super(); this.source = source; } iterator() { const sourceIterator = this.source.iterator(); let index = 0; return { next: () => { const result = sourceIterator.next(); if (result.done) { return { done: true, value: void 0 }; } return { done: false, value: [result.value, index++] }; } }; } }; var GroupedIterator = class extends AbstractIterable { constructor(source, chunkSize) { super(); this.buffer = []; this.isDone = false; this.sourceIterator = source.iterator(); this.chunkSize = chun