@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
1,529 lines (1,516 loc) • 99.4 kB
TypeScript
/**
* None represents an optional value that is not present
*/
declare class NoneImpl implements Option<never> {
get isSome(): boolean;
get isNone(): boolean;
get(): never;
getOrElse<B>(defaultValue: B): B;
getOrCall<B>(f: () => B): B;
getOrThrow(error: Error): never;
map<B>(_f: (a: never) => B): Option<B>;
mapOr<B>(defaultValue: B, _f: (a: never) => B): Option<B>;
flatMap<B>(_f: (a: never) => Option<B>): Option<B>;
orElse<B>(alternative: Option<B>): Option<B>;
orCall<B>(f: () => Option<B>): Option<B>;
filter(_predicate: (a: never) => boolean): Option<never>;
forEach(_f: (a: never) => void): void;
toArray(): never[];
toEither<E>(left: E): Either$1<E, never>;
match<B>(patterns: {
Some: (value: never) => B;
None: () => B;
}): B;
toString(): string;
}
declare const None: NoneImpl;
declare function Some<A>(value: A): Option<A>;
/**
* Option<A> represents an optional value that may or may not be present.
* It's a type-safe alternative to using null or undefined.
*
* @example
* ```ts
* import { Option, Some, None } from 'scats';
*
* // Creating options
* const a = Some(42);
* const b = None;
* const c = Option.fromNullable(maybeNull);
*
* // Using options
* const result = a
* .map(n => n * 2)
* .flatMap(n => n > 50 ? Some(n) : None)
* .getOrElse(0);
* ```
*/
/**
* Option<A> interface that all option implementations must satisfy
*/
interface Option<A> {
/**
* Returns true if the option is a Some, false otherwise
*/
readonly isSome: boolean;
/**
* Returns true if the option is a None, false otherwise
*/
readonly isNone: boolean;
/**
* Returns the value if this is a Some, otherwise throws an error
* @throws Error if the option is None
*/
get(): A;
/**
* Returns the value if this is a Some, otherwise returns the provided default value
*/
getOrElse<B>(defaultValue: B): A | B;
/**
* Returns the value if this is a Some, otherwise returns the result of the provided function
*/
getOrCall<B>(f: () => B): A | B;
/**
* Returns the value if this is a Some, otherwise throws the provided error
*/
getOrThrow(error: Error): A;
/**
* Maps the value if this is a Some, otherwise returns None
*/
map<B>(f: (a: A) => B): Option<B>;
/**
* Maps the value if this is a Some, otherwise returns the provided default value wrapped in Some
*/
mapOr<B>(defaultValue: B, f: (a: A) => B): Option<B>;
/**
* Returns the result of applying f if this is a Some, otherwise returns None
*/
flatMap<B>(f: (a: A) => Option<B>): Option<B>;
/**
* Returns the option if it is a Some, otherwise returns the provided option
*/
orElse<B>(alternative: Option<B>): Option<A | B>;
/**
* Returns the option if it is a Some, otherwise returns the result of the provided function
*/
orCall<B>(f: () => Option<B>): Option<A | B>;
/**
* Returns None if the predicate is not satisfied, otherwise returns this option
*/
filter(predicate: (a: A) => boolean): Option<A>;
/**
* Executes the provided function if this is a Some
*/
forEach(f: (a: A) => void): void;
/**
* Converts the option to an array with the value if it's a Some, or an empty array if it's a None
*/
toArray(): A[];
/**
* Converts this option to an Either with the provided left value if this is a None
*/
toEither<E>(left: E): Either$1<E, A>;
/**
* Returns the result of applying the appropriate function
*/
match<B>(patterns: {
Some: (value: A) => B;
None: () => B;
}): B;
}
declare namespace Option {
/**
* Creates an Option from a nullable value
*/
function fromNullable<A>(value: A | null | undefined): Option<A>;
/**
* Creates an Option from a function that might throw
*/
function tryCatch<A>(f: () => A): Option<A>;
/**
* Returns the first Some in the list, or None if all are None
*/
function firstSome<A>(...options: Option<A>[]): Option<A>;
/**
* Returns a Some containing an array of all values if all options are Some, None otherwise
*/
function sequence<A>(options: Option<A>[]): Option<A[]>;
/**
* Maps an array of values using a function that returns an Option, then sequences the result
*/
function traverse<A, B>(values: A[], f: (a: A) => Option<B>): Option<B[]>;
}
interface Either$1<E, A> {
isLeft: boolean;
isRight: boolean;
get(): A;
getLeft(): E;
}
/**
* Either<E, A> represents a value of one of two possible types: Left (E) or Right (A).
* Left is conventionally used for errors, while Right is used for success.
*
* @example
* ```ts
* import { Either, Left, Right } from 'scats';
*
* // Creating eithers
* const success = Right(42);
* const failure = Left(new Error("Something went wrong"));
*
* // Using eithers
* const result = success
* .map(n => n * 2)
* .flatMap(n => n > 50 ? Right(n) : Left("Value too small"))
* .getOrElse(0);
* ```
*/
/**
* Creates a Left instance
*/
declare function Left<E, A = never>(left: E): Either<E, A>;
/**
* Creates a Right instance
*/
declare function Right<A, E = never>(right: A): Either<E, A>;
/**
* Either<E, A> interface that all Either implementations must satisfy
*/
interface Either<E, A> {
/**
* Returns true if this is a Left, false otherwise
*/
readonly isLeft: boolean;
/**
* Returns true if this is a Right, false otherwise
*/
readonly isRight: boolean;
/**
* Returns the value from this Right, or throws an error if this is a Left
* @throws Error if this is a Left
*/
get(): A;
/**
* Returns the left value if this is a Left, or throws an error if this is a Right
* @throws Error if this is a Right
*/
getLeft(): E;
/**
* Returns the value from this Right, or returns the provided default value if this is a Left
*/
getOrElse<B>(defaultValue: B): A | B;
/**
* Returns the value from this Right, or returns the result of the provided function if this is a Left
*/
getOrCall<B>(f: (e: E) => B): A | B;
/**
* Returns the value from this Right, or throws the provided error if this is a Left
*/
getOrThrow(error: Error): A;
/**
* Maps the Right value if this is a Right, otherwise returns this Left unchanged
*/
map<B>(f: (a: A) => B): Either<E, B>;
/**
* Maps the Left value if this is a Left, otherwise returns this Right unchanged
*/
mapLeft<F>(f: (e: E) => F): Either<F, A>;
/**
* Returns the result of applying f if this is a Right, otherwise returns this Left unchanged
*/
flatMap<B>(f: (a: A) => Either<E, B>): Either<E, B>;
/**
* Returns this Right if this is a Right, otherwise returns the provided alternative
*/
orElse<F, B>(alternative: Either<F, B>): Either<E | F, A | B>;
/**
* Returns this Right if this is a Right, otherwise returns the result of the provided function
*/
orCall<F, B>(f: (e: E) => Either<F, B>): Either<E | F, A | B>;
/**
* Executes one of the provided functions based on whether this is a Left or a Right
*/
fold<B>(onLeft: (e: E) => B, onRight: (a: A) => B): B;
/**
* Executes the provided function if this is a Right
*/
forEach(f: (a: A) => void): void;
/**
* Executes the provided function if this is a Left
*/
forEachLeft(f: (e: E) => void): void;
/**
* Converts this Either to an Option, discarding the Left value if this is a Left
*/
toOption(): Option<A>;
/**
* Swaps the Left and Right values of this Either
*/
swap(): Either<A, E>;
/**
* Returns the result of applying the appropriate function
*/
match<B>(patterns: {
Left: (value: E) => B;
Right: (value: A) => B;
}): B;
}
/**
* Either namespace containing utility functions
*/
declare namespace Either {
/**
* Creates an Either from a function that might throw, capturing the error in the Left
*/
function tryCatch<A>(f: () => A): Either<unknown, A>;
/**
* Returns a Right containing an array of all values if all inputs are Right, otherwise returns the first Left
*/
function sequence<E, A>(eithers: Either<E, A>[]): Either<E, A[]>;
/**
* Maps an array of values using a function that returns an Either, then sequences the result
*/
function traverse<E, A, B>(values: A[], f: (a: A) => Either<E, B>): Either<E, B[]>;
}
/**
* Try<A> represents a computation that may either result in a value of type A
* or an exception. It's similar to Either<Error, A> but specifically for handling exceptions.
*
* @example
* ```ts
* import { Try, Success, Failure, TryAsync } from 'scats';
*
* // Creating instances
* const a = Try.of(() => JSON.parse('{"valid": "json"}'));
* const b = Try.of(() => JSON.parse('invalid json'));
*
* // Using Try
* const result = a
* .map(obj => obj.valid)
* .flatMap(str => Try.of(() => str.toUpperCase()))
* .getOrElse("default");
*
* // Async version
* const asyncResult = await TryAsync.of(async () => {
* const response = await fetch('https://api.example.com');
* return response.json();
* }).map(data => data.value).toPromise();
* ```
*/
/**
* Creates a Success instance
*/
declare function Success<A>(value: A): Try<A>;
/**
* Creates a Failure instance
*/
declare function Failure<A>(error: Error): Try<A>;
/**
* Try<A> interface that all Try implementations must satisfy
*/
interface Try<A> {
/**
* Returns true if this is a Success, false otherwise
*/
readonly isSuccess: boolean;
/**
* Returns true if this is a Failure, false otherwise
*/
readonly isFailure: boolean;
/**
* Returns the value if this is a Success, or throws the error if this is a Failure
* @throws Error if this is a Failure
*/
get(): A;
/**
* Returns the value if this is a Success, or returns the provided default value if this is a Failure
*/
getOrElse<B>(defaultValue: B): A | B;
/**
* Returns the error if this is a Failure, or throws if this is a Success
* @throws Error if this is a Success
*/
getError(): Error;
/**
* Returns a Try containing the exception if this is a Failure, or a Failure if this is a Success
*/
failed(): Try<Error>;
/**
* Maps the value if this is a Success, otherwise returns this Failure unchanged
*/
map<B>(f: (a: A) => B): Try<B>;
/**
* Returns the result of applying f if this is a Success, otherwise returns this Failure unchanged
*/
flatMap<B>(f: (a: A) => Try<B>): Try<B>;
/**
* Recovers from a failure by returning the result of the provided function
*/
recover<B>(f: (error: Error) => B): Try<A | B>;
/**
* Recovers from a failure by returning the result of the provided function
*/
recoverWith<B>(f: (error: Error) => Try<B>): Try<A | B>;
/**
* Transforms this Try to another Try using the provided functions
*/
transform<B>(s: (a: A) => Try<B>, f: (error: Error) => Try<B>): Try<B>;
/**
* Converts this Try to an Option, discarding the error if this is a Failure
*/
toOption(): Option<A>;
/**
* Converts this Try to an Either with the error as Left and value as Right
*/
toEither(): Either<Error, A>;
/**
* Executes one of the provided functions based on whether this is a Success or a Failure
*/
fold<B>(onFailure: (error: Error) => B, onSuccess: (value: A) => B): B;
/**
* Returns the result of applying the appropriate function
*/
match<B>(patterns: {
Success: (value: A) => B;
Failure: (error: Error) => B;
}): B;
}
/**
* Try namespace containing utility functions
*/
declare namespace Try {
/**
* Creates a Try from a function that might throw
*/
function of<A>(f: () => A): Try<A>;
/**
* Returns a Success containing an array of all values if all tries are Success, otherwise returns the first Failure
*/
function sequence<A>(tries: Try<A>[]): Try<A[]>;
/**
* Maps an array of values using a function that returns a Try, then sequences the result
*/
function traverse<A, B>(values: A[], f: (a: A) => Try<B>): Try<B[]>;
}
/**
* TryAsync<A> represents an asynchronous computation that may either result in a value of type A
* or an exception. It's the asynchronous counterpart to Try<A>.
*/
interface TryAsync<A> {
/**
* Maps the value if this is a Success, otherwise returns this Failure unchanged
*/
map<B>(f: (a: A) => B | Promise<B>): TryAsync<B>;
/**
* Returns the result of applying f if this is a Success, otherwise returns this Failure unchanged
*/
flatMap<B>(f: (a: A) => TryAsync<B> | Promise<TryAsync<B>>): TryAsync<B>;
/**
* Recovers from a failure by returning the result of the provided function
*/
recover<B>(f: (error: Error) => B | Promise<B>): TryAsync<A | B>;
/**
* Recovers from a failure by returning the result of the provided function
*/
recoverWith<B>(f: (error: Error) => TryAsync<B> | Promise<TryAsync<B>>): TryAsync<A | B>;
/**
* Converts this async Try to a Promise
*/
toPromise(): Promise<A>;
}
/**
* TryAsync namespace containing utility functions
*/
declare namespace TryAsync {
/**
* Creates a TryAsync from a function that returns a Promise
*/
function of<A>(f: () => Promise<A>): TryAsync<A>;
/**
* Creates a successful TryAsync
*/
function success<A>(value: A): TryAsync<A>;
/**
* Creates a failed TryAsync
*/
function failure<A>(error: Error): TryAsync<A>;
/**
* Converts a Promise to a TryAsync
*/
function fromPromise<A>(promise: Promise<A>): TryAsync<A>;
}
/**
* A default global execution context backed by the JavaScript event loop.
*/
declare class GlobalExecutionContext implements ExecutionContext {
/**
* Executes a task asynchronously.
*/
execute(task: () => void): void;
/**
* Reports a failure to the console.
*/
reportFailure(cause: Error): void;
}
/**
* An execution context that executes tasks synchronously in the current thread.
* This is mainly for testing and should be avoided in production.
*/
declare class SynchronousExecutionContext implements ExecutionContext {
/**
* Executes a task immediately in the current thread.
*/
execute(task: () => void): void;
/**
* Reports a failure to the console.
*/
reportFailure(cause: Error): void;
}
/**
* The execution context is the environment where a computation runs.
*/
interface ExecutionContext {
/**
* Executes a task in this execution context.
*/
execute(task: () => void): void;
/**
* Reports an exception that occurred during execution.
*/
reportFailure(cause: Error): void;
}
/**
* Execution context utility methods.
*/
declare const ExecutionContext: {
/**
* The global execution context.
*/
global: GlobalExecutionContext;
/**
* A synchronous execution context for testing.
*/
synchronous: SynchronousExecutionContext;
/**
* Creates an execution context from a function that executes tasks.
*/
fromExecutor(executor: (task: () => void) => void, reporter?: (cause: Error) => void): ExecutionContext;
};
/**
* List<A> represents an immutable linked list structure.
* It's a singly-linked list that supports efficient prepend operations.
*
* @example
* ```ts
* import { List } from 'scats';
*
* // Creating lists
* const a = List.of(1, 2, 3);
* const b = List.empty<number>();
* const c = a.prepend(0);
*
* // Using lists
* const doubled = a.map(n => n * 2);
* const summed = a.foldLeft(0, (acc, n) => acc + n);
* const filtered = a.filter(n => n % 2 === 0);
* ```
*/
/**
* List<A> interface that all List implementations must satisfy
*/
interface List<A> extends Iterable<A> {
/**
* Returns true if this list is empty, false otherwise
*/
readonly isEmpty: boolean;
/**
* Returns the number of elements in this list
*/
readonly size: number;
/**
* Returns the first element of this list, or throws an error if the list is empty
* @throws Error if the list is empty
*/
head(): A;
/**
* Returns the rest of this list (all elements except the head), or throws an error if the list is empty
* @throws Error if the list is empty
*/
tail(): List<A>;
/**
* Returns the first element of this list as an Option, or None if the list is empty
*/
headOption(): Option<A>;
/**
* Returns the rest of this list as an Option, or None if the list is empty
*/
tailOption(): Option<List<A>>;
/**
* Returns a new list with the provided element prepended to this list
*/
prepend(element: A): List<A>;
/**
* Returns a new list with the provided elements appended to this list
*/
append(element: A): List<A>;
/**
* Returns a new list that is the result of concatenating this list with the provided list
*/
concat(that: List<A>): List<A>;
/**
* Returns a new list that is the result of applying the provided function to each element
*/
map<B>(f: (a: A) => B): List<B>;
/**
* Returns a new list that is the result of applying the provided function to each element
* and flattening the results
*/
flatMap<B>(f: (a: A) => List<B>): List<B>;
/**
* Returns a new list containing only the elements that satisfy the provided predicate
*/
filter(predicate: (a: A) => boolean): List<A>;
/**
* Returns a tuple of two lists, where the first list contains all elements that satisfy
* the provided predicate, and the second list contains all elements that don't satisfy the predicate
*/
partition(predicate: (a: A) => boolean): [List<A>, List<A>];
/**
* Returns true if any element in this list satisfies the provided predicate, false otherwise
*/
exists(predicate: (a: A) => boolean): boolean;
/**
* Returns true if all elements in this list satisfy the provided predicate, false otherwise
*/
forAll(predicate: (a: A) => boolean): boolean;
/**
* Returns the result of applying the provided function to each element, starting with the provided initial value
*/
foldLeft<B>(initial: B, f: (acc: B, a: A) => B): B;
/**
* Returns the result of applying the provided function to each element, starting with the provided initial value,
* working from right to left
*/
foldRight<B>(initial: B, f: (a: A, acc: B) => B): B;
/**
* Executes the provided function for each element in this list
*/
forEach(f: (a: A) => void): void;
/**
* Returns a new list containing the elements at the specified indices
*/
slice(start: number, end?: number): List<A>;
/**
* Returns a new list with the first n elements
*/
take(n: number): List<A>;
/**
* Returns a new list with all elements except the first n
*/
drop(n: number): List<A>;
/**
* Returns a new list with elements while the predicate is satisfied
*/
takeWhile(predicate: (a: A) => boolean): List<A>;
/**
* Returns a new list without elements while the predicate is satisfied
*/
dropWhile(predicate: (a: A) => boolean): List<A>;
/**
* Returns the element at the specified index, or throws an error if the index is out of bounds
* @throws Error if the index is out of bounds
*/
get(index: number): A;
/**
* Returns the element at the specified index as an Option, or None if the index is out of bounds
*/
getOption(index: number): Option<A>;
/**
* Returns a new list with the element at the specified index replaced with the provided element,
* or the same list if the index is out of bounds
*/
updateAt(index: number, element: A): List<A>;
/**
* Returns the index of the first occurrence of the specified element, or -1 if the element is not found
*/
indexOf(element: A): number;
/**
* Returns true if this list contains the specified element, false otherwise
*/
contains(element: A): boolean;
/**
* Returns a new list with distinct elements (removes duplicates)
*/
distinct(): List<A>;
/**
* Returns a new list with the elements in reverse order
*/
reverse(): List<A>;
/**
* Returns a new list sorted according to the natural ordering of the elements
*/
sorted(compareFn?: (a: A, b: A) => number): List<A>;
/**
* Converts this list to an array
*/
toArray(): A[];
/**
* Returns a string representation of this list
*/
toString(): string;
}
/**
* List namespace containing utility functions
*/
declare namespace List {
/**
* Creates a list containing the provided elements
*/
function of<A>(...elements: A[]): List<A>;
/**
* Creates a list from an array
*/
function fromArray<A>(array: A[]): List<A>;
/**
* Creates a list from an iterable
*/
function fromIterable<A>(iterable: Iterable<A>): List<A>;
/**
* Creates an empty list
*/
function empty<A>(): List<A>;
/**
* Creates a list with elements produced by the specified function
*/
function fill<A>(n: number, f: (index: number) => A): List<A>;
/**
* Creates a list with the specified element repeated n times
*/
function repeat<A>(element: A, n: number): List<A>;
/**
* Creates a list with numbers from start (inclusive) to end (exclusive)
*/
function range(start: number, end: number, step?: number): List<number>;
/**
* Zips two lists together, element by element
*/
function zip<A, B>(as: List<A>, bs: List<B>): List<[A, B]>;
/**
* Maps two lists with the provided function
*/
function map2<A, B, C>(as: List<A>, bs: List<B>, f: (a: A, b: B) => C): List<C>;
}
/**
* Map<K, V> represents an immutable key-value map.
* It's implemented as a balanced binary search tree for efficient operations.
*
* @example
* ```ts
* import { Map } from 'scats';
*
* // Creating maps
* const a = Map.of([["a", 1], ["b", 2], ["c", 3]]);
* const b = Map.empty<string, number>();
* const c = a.set("d", 4);
*
* // Using maps
* const value = a.get("a"); // Some(1)
* const notFound = a.get("z"); // None
* const updated = a.update("a", n => n * 2); // Map(["a", 2], ["b", 2], ["c", 3])
* ```
*/
/**
* Map<K, V> interface that all Map implementations must satisfy
*/
interface Map<K, V> {
/**
* Returns true if this map is empty, false otherwise
*/
readonly isEmpty: boolean;
/**
* Returns the number of key-value pairs in this map
*/
readonly size: number;
/**
* Returns the keys in this map
*/
readonly keys: List<K>;
/**
* Returns the values in this map
*/
readonly values: List<V>;
/**
* Returns the key-value pairs in this map
*/
readonly entries: List<[K, V]>;
/**
* Returns the value associated with the specified key as an Option, or None if the key is not found
*/
get(key: K): Option<V>;
/**
* Returns the value associated with the specified key, or the provided default value if the key is not found
*/
getOrElse<U>(key: K, defaultValue: U): V | U;
/**
* Returns a new map with the specified key-value pair added or updated
*/
set(key: K, value: V): Map<K, V>;
/**
* Returns a new map with the specified key-value pairs added or updated
*/
setAll(entries: Iterable<[K, V]>): Map<K, V>;
/**
* Returns a new map with the specified key-value pair removed
*/
remove(key: K): Map<K, V>;
/**
* Returns a new map with the specified keys removed
*/
removeAll(keys: Iterable<K>): Map<K, V>;
/**
* Returns a new map with the value associated with the specified key updated by applying the provided function,
* or the same map if the key is not found
*/
update(key: K, f: (value: V) => V): Map<K, V>;
/**
* Returns a new map with the value associated with the specified key updated by applying the provided function,
* or a new map with the specified key-value pair added if the key is not found
*/
updateOrSet(key: K, f: (value: Option<V>) => V): Map<K, V>;
/**
* Returns a new map that is the result of merging this map with the specified map
*/
merge(that: Map<K, V>): Map<K, V>;
/**
* Returns a new map that is the result of applying the provided function to each key-value pair
*/
map<W>(f: (value: V, key: K) => W): Map<K, W>;
/**
* Returns a new map containing only the key-value pairs that satisfy the provided predicate
*/
filter(predicate: (value: V, key: K) => boolean): Map<K, V>;
/**
* Returns true if any key-value pair in this map satisfies the provided predicate, false otherwise
*/
exists(predicate: (value: V, key: K) => boolean): boolean;
/**
* Returns true if all key-value pairs in this map satisfy the provided predicate, false otherwise
*/
forAll(predicate: (value: V, key: K) => boolean): boolean;
/**
* Returns the result of applying the provided function to each key-value pair, starting with the provided initial value
*/
foldLeft<U>(initial: U, f: (acc: U, value: V, key: K) => U): U;
/**
* Executes the provided function for each key-value pair in this map
*/
forEach(f: (value: V, key: K) => void): void;
/**
* Returns true if this map contains the specified key, false otherwise
*/
has(key: K): boolean;
/**
* Returns a native JavaScript Map containing the same key-value pairs as this map
*/
toNativeMap(): globalThis.Map<K, V>;
/**
* Returns a string representation of this map
*/
toString(): string;
}
/**
* Map namespace containing utility functions
*/
declare namespace Map {
/**
* Creates a map from the provided entries
*/
function of<K, V>(entries: Iterable<[K, V]>): Map<K, V>;
/**
* Creates a map from a list of key-value pairs
*/
function fromList<K, V>(entries: List<[K, V]>): Map<K, V>;
/**
* Creates a map from a native JavaScript Map
*/
function fromNativeMap<K, V>(map: globalThis.Map<K, V>): Map<K, V>;
/**
* Creates an empty map
*/
function empty<K, V>(): Map<K, V>;
/**
* Creates a map from a list of keys and a function that computes values
*/
function fromKeys<K, V>(keys: List<K>, f: (key: K) => V): Map<K, V>;
/**
* Creates a map from a list of values and a function that computes keys
*/
function fromValues<K, V>(values: List<V>, f: (value: V) => K): Map<K, V>;
}
/**
* Set<A> represents an immutable set of unique values.
* It's a collection of unique elements with efficient add, remove, and contains operations.
*
* @example
* ```ts
* import { Set } from 'scats';
*
* // Creating sets
* const a = Set.of(1, 2, 3);
* const b = Set.empty<number>();
* const c = a.add(4);
*
* // Using sets
* const union = a.union(Set.of(3, 4, 5)); // Set(1, 2, 3, 4, 5)
* const intersection = a.intersection(Set.of(2, 3, 4)); // Set(2, 3)
* const difference = a.difference(Set.of(2, 3)); // Set(1)
* ```
*/
/**
* Set<A> interface that all Set implementations must satisfy
*/
interface Set<A> {
/**
* Returns true if this set is empty, false otherwise
*/
readonly isEmpty: boolean;
/**
* Returns the number of elements in this set
*/
readonly size: number;
/**
* Returns the elements in this set
*/
readonly values: List<A>;
/**
* Returns true if this set contains the specified element, false otherwise
*/
contains(element: A): boolean;
/**
* Returns a new set with the specified element added
*/
add(element: A): Set<A>;
/**
* Returns a new set with the specified elements added
*/
addAll(elements: Iterable<A>): Set<A>;
/**
* Returns a new set with the specified element removed
*/
remove(element: A): Set<A>;
/**
* Returns a new set with the specified elements removed
*/
removeAll(elements: Iterable<A>): Set<A>;
/**
* Returns a new set that is the union of this set and the specified set
*/
union(that: Set<A>): Set<A>;
/**
* Returns a new set that is the intersection of this set and the specified set
*/
intersection(that: Set<A>): Set<A>;
/**
* Returns a new set that is the difference of this set and the specified set
*/
difference(that: Set<A>): Set<A>;
/**
* Returns true if this set is a subset of the specified set, false otherwise
*/
isSubsetOf(that: Set<A>): boolean;
/**
* Returns true if this set is a proper subset of the specified set, false otherwise
*/
isProperSubsetOf(that: Set<A>): boolean;
/**
* Returns true if this set is a superset of the specified set, false otherwise
*/
isSupersetOf(that: Set<A>): boolean;
/**
* Returns true if this set is a proper superset of the specified set, false otherwise
*/
isProperSupersetOf(that: Set<A>): boolean;
/**
* Returns a new set that is the result of applying the provided function to each element
*/
map<B>(f: (a: A) => B): Set<B>;
/**
* Returns a new set containing only the elements that satisfy the provided predicate
*/
filter(predicate: (a: A) => boolean): Set<A>;
/**
* Returns true if any element in this set satisfies the provided predicate, false otherwise
*/
exists(predicate: (a: A) => boolean): boolean;
/**
* Returns true if all elements in this set satisfy the provided predicate, false otherwise
*/
forAll(predicate: (a: A) => boolean): boolean;
/**
* Returns the result of applying the provided function to each element, starting with the provided initial value
*/
foldLeft<B>(initial: B, f: (acc: B, a: A) => B): B;
/**
* Executes the provided function for each element in this set
*/
forEach(f: (a: A) => void): void;
/**
* Partitions this set into two sets according to the provided predicate
*/
partition(predicate: (a: A) => boolean): [Set<A>, Set<A>];
/**
* Converts this set to a native JavaScript Set
*/
toNativeSet(): globalThis.Set<A>;
/**
* Converts this set to an array
*/
toArray(): A[];
/**
* Returns a string representation of this set
*/
toString(): string;
}
/**
* Set namespace containing utility functions
*/
declare namespace Set {
/**
* Creates a set containing the provided elements
*/
function of<A>(...elements: A[]): Set<A>;
/**
* Creates a set from the provided iterable
*/
function fromIterable<A>(iterable: Iterable<A>): Set<A>;
/**
* Creates a set from a native JavaScript Set
*/
function fromNativeSet<A>(set: globalThis.Set<A>): Set<A>;
/**
* Creates an empty set
*/
function empty<A>(): Set<A>;
}
/**
* Represents a collection of elements that can be iterated over.
* This trait is the base for all collection types in the library.
*/
interface Iterable$1<A> {
/**
* Returns an iterator that yields every element in the collection.
*/
iterator(): Iterator<A>;
/**
* Implements the iterable protocol for for...of loops
*/
[Symbol.iterator](): Iterator<A>;
/**
* Executes a function for each element in the collection.
*/
forEach(f: (a: A) => void): void;
/**
* Returns a new collection containing the results of applying the given function
* to each element of this collection.
*/
map<B>(f: (a: A) => B): Iterable$1<B>;
/**
* Returns a new collection containing the results of applying the given collection-valued function
* to each element of this collection and concatenating the results.
*/
flatMap<B>(f: (a: A) => Iterable$1<B>): Iterable$1<B>;
/**
* Returns a new collection containing the results of applying the given partial function
* to each element of this collection for which it is defined and collecting the results.
*/
collect<B>(f: (a: A) => Option<B>): Iterable$1<B>;
/**
* Returns a new collection consisting of the elements of both this collection and the other collection.
*/
concat(other: Iterable$1<A>): Iterable$1<A>;
/**
* Returns a new collection consisting of those elements of this collection that satisfy the predicate.
*/
filter(p: (a: A) => boolean): Iterable$1<A>;
/**
* Returns a new collection consisting of those elements of this collection that do not satisfy the predicate.
*/
filterNot(p: (a: A) => boolean): Iterable$1<A>;
/**
* Returns a non-strict filter of this collection.
* Subsequent calls to map, flatMap, foreach, and withFilter will only apply to those elements
* of this collection for which the condition p is true.
*/
withFilter(p: (a: A) => boolean): Iterable$1<A>;
/**
* Returns the first element of this collection.
* @throws Error if the collection is empty
*/
head(): A;
/**
* Returns the first element of this collection in an option value, or None if the collection is empty.
*/
headOption(): Option<A>;
/**
* Returns the last element of this collection.
* @throws Error if the collection is empty
*/
last(): A;
/**
* Returns the last element of this collection in an option value, or None if the collection is empty.
*/
lastOption(): Option<A>;
/**
* Returns an option containing the first element in this collection that satisfies the predicate,
* or None if no element qualifies.
*/
find(p: (a: A) => boolean): Option<A>;
/**
* Returns the rest of the collection except the first element.
* @throws Error if the collection is empty
*/
tail(): Iterable$1<A>;
/**
* Returns the rest of the collection except the last element.
* @throws Error if the collection is empty
*/
init(): Iterable$1<A>;
/**
* Returns a collection consisting of elements in some index range of this collection.
*/
slice(from: number, to: number): Iterable$1<A>;
/**
* Returns a collection consisting of the first n elements of this collection.
*/
take(n: number): Iterable$1<A>;
/**
* Returns the rest of the collection except the first n elements.
*/
drop(n: number): Iterable$1<A>;
/**
* Returns the longest prefix of elements in the collection that all satisfy the predicate.
*/
takeWhile(p: (a: A) => boolean): Iterable$1<A>;
/**
* Returns the collection without the longest prefix of elements that all satisfy the predicate.
*/
dropWhile(p: (a: A) => boolean): Iterable$1<A>;
/**
* Returns a collection consisting of the last n elements of this collection.
*/
takeRight(n: number): Iterable$1<A>;
/**
* Returns the rest of the collection except the last n elements.
*/
dropRight(n: number): Iterable$1<A>;
/**
* Split this collection at a position, giving the pair of collections (take n, drop n).
*/
splitAt(n: number): [Iterable$1<A>, Iterable$1<A>];
/**
* Split this collection according to a predicate, giving the pair of collections
* (takeWhile p, dropWhile p).
*/
span(p: (a: A) => boolean): [Iterable$1<A>, Iterable$1<A>];
/**
* Split this collection into a pair of collections; one with elements that satisfy the predicate,
* the other with elements that do not.
*/
partition(p: (a: A) => boolean): [Iterable$1<A>, Iterable$1<A>];
/**
* Partition this collection into a map of collections according to a discriminator function.
*/
groupBy<K>(f: (a: A) => K): globalThis.Map<K, Iterable$1<A>>;
/**
* Tests whether the predicate holds for all elements of this collection.
*/
forall(p: (a: A) => boolean): boolean;
/**
* Tests whether the predicate holds for some element of this collection.
*/
exists(p: (a: A) => boolean): boolean;
/**
* Returns the number of elements in this collection that satisfy the predicate.
*/
count(p: (a: A) => boolean): number;
/**
* Apply binary operation op between successive elements of this collection,
* going left to right and starting with z.
*/
foldLeft<B>(z: B, op: (b: B, a: A) => B): B;
/**
* Apply binary operation op between successive elements of this collection,
* going right to left and starting with z.
*/
foldRight<B>(z: B, op: (a: A, b: B) => B): B;
/**
* Apply binary operation op between successive elements of non-empty collection,
* going left to right.
* @throws Error if the collection is empty
*/
reduceLeft(op: (a: A, b: A) => A): A;
/**
* Apply binary operation op between successive elements of non-empty collection,
* going right to left.
* @throws Error if the collection is empty
*/
reduceRight(op: (a: A, b: A) => A): A;
/**
* Returns the sum of the numeric element values of this collection.
* @throws Error if the collection is empty or contains non-numeric values
*/
sum(): number;
/**
* Returns the product of the numeric element values of this collection.
* @throws Error if the collection is empty or contains non-numeric values
*/
product(): number;
/**
* Returns the minimum of the ordered element values of this collection.
* @throws Error if the collection is empty
*/
min(): A;
/**
* Returns the maximum of the ordered element values of this collection.
* @throws Error if the collection is empty
*/
max(): A;
/**
* Like min but returns None if the collection is empty.
*/
minOption(): Option<A>;
/**
* Like max but returns None if the collection is empty.
*/
maxOption(): Option<A>;
/**
* Converts the collection to a string that shows all elements between separators
* enclosed in strings start and end.
*/
mkString(start?: string, sep?: string, end?: string): string;
/**
* Returns a collection of pairs of corresponding elements from this collection and the other collection.
*/
zip<B>(other: Iterable$1<B>): Iterable$1<[A, B]>;
/**
* Returns a collection of pairs of corresponding elements from this collection and the other collection,
* where the shorter sequence is extended to match the longer one by appending elements x or y.
*/
zipAll<B>(other: Iterable$1<B>, thisElem: A, thatElem: B): Iterable$1<[A, B]>;
/**
* Returns a collection of pairs of elements from this collection with their indices.
*/
zipWithIndex(): Iterable$1<[A, number]>;
/**
* Tests whether the collection is empty.
*/
isEmpty(): boolean;
/**
* Tests whether the collection contains elements.
*/
nonEmpty(): boolean;
/**
* Returns the number of elements in the collection.
*/
size(): number;
/**
* Returns the number of elements, if this one takes constant time to compute, otherwise -1.
*/
knownSize(): number;
/**
* Returns a negative value if this collection is shorter than the other collection,
* a positive value if it is longer, and 0 if they have the same size.
*
* Can also be called with a number to compare the collection size with that number.
*/
sizeCompare(other: Iterable$1<any> | number): number;
/**
* Returns an iterator that yields fixed-sized "chunks" of this collection.
*/
grouped(size: number): Iterator<Iterable$1<A>> & Iterable$1<Iterable$1<A>>;
/**
* Returns an iterator that yields a sliding fixed-sized window of elements in this collection.
*/
sliding(size: number): Iterator<Iterable$1<A>> & Iterable$1<Iterable$1<A>>;
/**
* Converts the collection to an array.
*/
toArray(): A[];
/**
* Converts the collection to a list.
*/
toList(): List<A>;
/**
* Converts the collection to a set.
*/
toSet(): Set<A>;
/**
* Converts the collection to a map.
* @throws Error if the collection does not have pairs as elements
*/
toMap<K, V>(): Map<K, V>;
}
/**
* Abstract base class implementing the Iterable trait.
* This provides default implementations for many methods based on the iterator method.
*/
declare abstract class AbstractIterable<A> implements Iterable$1<A> {
abstract iterator(): Iterator<A>;
[Symbol.iterator](): Iterator<A>;
forEach(f: (a: A) => void): void;
map<B>(f: (a: A) => B): Iterable$1<B>;
flatMap<B>(f: (a: A) => Iterable$1<B>): Iterable$1<B>;
collect<B>(f: (a: A) => Option<B>): Iterable$1<B>;
concat(other: Iterable$1<A>): Iterable$1<A>;
filter(p: (a: A) => boolean): Iterable$1<A>;
filterNot(p: (a: A) => boolean): Iterable$1<A>;
withFilter(p: (a: A) => boolean): Iterable$1<A>;
head(): A;
headOption(): Option<A>;
last(): A;
lastOption(): Option<A>;
find(p: (a: A) => boolean): Option<A>;
tail(): Iterable$1<A>;
init(): Iterable$1<A>;
slice(from: number, to: number): Iterable$1<A>;
take(n: number): Iterable$1<A>;
drop(n: number): Iterable$1<A>;
takeWhile(p: (a: A) => boolean): Iterable$1<A>;
dropWhile(p: (a: A) => boolean): Iterable$1<A>;
takeRight(n: number): Iterable$1<A>;
dropRight(n: number): Iterable$1<A>;
splitAt(n: number): [Iterable$1<A>, Iterable$1<A>];
span(p: (a: A) => boolean): [Iterable$1<A>, Iterable$1<A>];
partition(p: (a: A) => boolean): [Iterable$1<A>, Iterable$1<A>];
groupBy<K>(f: (a: A) => K): globalThis.Map<K, Iterable$1<A>>;
forall(p: (a: A) => boolean): boolean;
exists(p: (a: A) => boolean): boolean;
count(p: (a: A) => boolean): number;
foldLeft<B>(z: B, op: (b: B, a: A) => B): B;
foldRight<B>(z: B, op: (a: A, b: B) => B): B;
reduceLeft(op: (a: A, b: A) => A): A;
reduceRight(op: (a: A, b: A) => A): A;
sum(): number;
product(): number;
min(): A;
max(): A;
minOption(): Option<A>;
maxOption(): Option<A>;
mkString(start?: string, sep?: string, end?: string): string;
zip<B>(other: Iterable$1<B>): Iterable$1<[A, B]>;
zipAll<B>(other: Iterable$1<B>, thisElem: A, thatElem: B): Iterable$1<[A, B]>;
zipWithIndex(): Iterable$1<[A, number]>;
isEmpty(): boolean;
nonEmpty(): boolean;
size(): number;
knownSize(): number;
sizeCompare(other: Iterable$1<any> | number): number;
grouped(size: number): Iterator<Iterable$1<A>> & Iterable$1<Iterable$1<A>>;
sliding(size: number): Iterator<Iterable$1<A>> & Iterable$1<Iterable$1<A>>;
toArray(): A[];
toList(): List<A>;
toSet(): Set<A>;
toMap<K, V>(): Map<K, V>;
}
/**
* The Seq trait represents sequences. A sequence is a kind of iterable that has a length
* and whose elements have fixed index positions, starting from 0.
*/
interface Seq<A> extends Iterable$1<A> {
/**
* Returns the element at the specified index.
*/
apply(i: number): A;
/**
* Tests whether an index is contained in this sequence's range.
*/
isDefinedAt(i: number): boolean;
/**
* Returns the index range of this sequence, from 0 to length - 1.
*/
indices(): Iterable$1<number>;
/**
* Compares the length of this sequence with a specified value.
* Returns -1 if shorter, 0 if equal, 1 if longer.
*/
lengthCompare(len: number): number;
/**
* Finds the index of the first occurrence of an element.
*/
indexOf(elem: A, from?: number): number;
/**
* Finds the index of the last occurrence of an element.
*/
lastIndexOf(elem: A, end?: number): number;
/**
* Finds the first index where a subsequence occurs.
*/
indexOfSlice<B>(that: Seq<B>, from?: number): number;
/**
* Finds the last index where a subsequence occurs.
*/
lastIndexOfSlice<B>(that: Seq<B>, end?: number): number;
/**
* Finds the first index where a predicate is satisfied.
*/
indexWhere(p: (a: A) => boolean, from?: number): number;
/**
* Finds the last index where a predicate is satisfied.
*/
lastIndexWhere(p: (a: A) => boolean, end?: number): number;
/**
* Returns the length of the longest segment of elements starting at a given index that all satisfy a predicate.
*/
segmentLength(p: (a: A) => boolean, from?: number): number;
/**
* Returns a new sequence with an element prepended.
*/
prepended(elem: A): Seq<A>;
/**
* Returns a new sequence with elements prepended.
*/
prependedAll<B>(prefix: Iterable$1<B>): Seq<A | B>;
/**
* Returns a new sequence with an element appended.
*/
appended(elem: A): Seq<A>;
/**
* Returns a new sequence with elements appended.
*/
appendedAll<B>(suffix: Iterable$1<B>): Seq<A | B>;
/**
* Returns a new sequence padded to a given length with a given value.
*/
padTo(len: number, elem: A): Seq<A>;
/**
* Returns a new sequence with a slice of another sequence patched in.
*/
patch<B>(from: number, patch: Seq<B>, replaced: number): Seq<A | B>;
/**
* Returns a new sequence with one element replaced.
*/
updated(index: number, elem: A): Seq<A>;
/**
* Returns a new sequence with elements sorted.
*/
sorted(implicit?: (a: A, b: A) => number): Seq<A>;
/**
* Returns a new sequence sorted according to a comparison function.
*/
sortWith(lt: (a: A, b: A) => boolean): Seq<A>;
/**
* Returns a new sequence sorted according to a key function.
*/
sortBy<B>(f: (a: A) => B, implicit?: (a: B, b: B) => number): Seq<A>;
/**
* Returns a new sequence with elements in reverse order.
*/
reverse(): Seq<A>;
/**
* Returns an iterator yielding elements in reverse order.
*/
reverseIterator(): Iterator<A>;
/**
* Tests whether this sequence starts with a given sequence.
*/
startsWith<B>(that: Seq<B>, offset?: number): boolean;
/**
* Tests whether this sequence ends with a given sequence.
*/
endsWith<B>(that: Seq<B>): boolean;
/**
* Tests whether this sequence contains a given value as an element.
*/
contains(elem: A): boolean;
/**
* Tests whether this sorted sequence contains a given value.
*/
search(elem: A): number;
/**
* Tests whether this sequence contains a given sequence as a slice.
*/
containsSlice<B>(that: Seq<B>): boolean;
/**
* Tests whether corresponding elements of this sequence and another satisfy a predicate.
*/
corresponds<B>(that: Seq<B>, p: (a: A, b: B) => boolean): boolean;
/**
* Returns the multi-set intersection of this sequence and another.
*/
intersect<B>(that: Seq<B>): Seq<A>;
/**
* Returns the multi-set difference of this sequence and another.
*/
diff<B>(that: Seq<B>): Seq<A>;
/**
* Returns a new sequence with no duplicate elements.
*/
distinct(): Seq<A>;
/**
* Returns a new sequence with no duplicate elements according to a transformation function.
*/
distinctBy<B>(f: (a: A) => B): Seq<A>;
}
/**
* The LinearSeq trait represents sequences that have efficient head and tail operations.
*/
interface LinearSeq<A> extends Seq<A> {
}
/**
* The IndexedSeq trait represents sequences that have efficient apply and length operations.
*/
interface IndexedSeq<A> extends Seq<A> {
}
/**
* The mutable IndexedSeq trait adds in-place operations.
*/
interface MutableIndexedSeq<A> extends IndexedSeq<A> {
/**
* Updates the element at the given index.
*/
update(index: number, elem: A): void;
/**
* Transforms all elements of this sequence in place.
*/
mapInPlace(f: (a: A) => A): this;
/**
* Sorts this sequence in place.
*/
sortInPlace(implicit?: (a: A, b: A) => number): this;
/**
* Sorts this sequence in place according to a comparison function.
*/
sortInPlaceWith(lt: (a: A, b: A) => boolean): this;
/**
* Sorts this sequence in place according to a key function.
*/
sortInPlaceBy<B>(f: (a: A) => B, implicit?: (a: B, b: B) => number): this;
}
/**
* The Buffer trait represents sequences that allow addition, insertion, and removal of elements.
*/
interface Buffer<A> extends MutableIndexedSeq<A> {
/**
* Appends an element to this buffer.
*/
append(elem: A): this;
/**
* Appends all elements of a collection to this buffer.
*/
appendAll<B extends A>(xs: Iterable$1<B>): this;
/**
* Prepends an element to this buffer.
*/
prepend(elem: A): this;
/**
* Prepends all elements of a collection to this buffer.
*/
prependAll<B extends A>(xs: Iterable$1<B>): this;
/**
* Inserts an element at a given index.
*/
insert(idx: number, elem: A): this;
/**
* Inserts elements at a given index.
*/
insertAll<B extends A>(idx: number, x