@openstage/monadyssey-core 3.0.0-beta.1 → 3.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/monadyssey.cjs.map +1 -1
- package/dist/monadyssey.d.ts +47 -45
- package/dist/monadyssey.mjs.map +1 -1
- package/dist/monadyssey.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/monadyssey.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"monadyssey.cjs","names":[],"sources":["../src/either.ts","../src/utils.ts","../src/option.ts","../src/non-empty-list.ts","../src/list.ts","../src/schedule.ts","../src/io.ts","../src/eval.ts","../src/reader.ts","../src/ordering.ts"],"sourcesContent":["/**\n * Represents a type which is either a Left (failure) or a Right (success).\n * Left typically stores an error or failure state, while Right stores a success value.\n */\nexport abstract class Either<A, B> {\n abstract type: \"Left\" | \"Right\";\n\n /**\n * Property to access the actual `Either` instance, enabling exhaustive type checking and type narrowing.\n * Use this when a switch statement needs to handle each subtype distinctly.\n *\n * @example\n * function isAlive(cat: Either<\"dead\", \"alive\">): boolean {\n * // switch is exhaustive without a default branch\n * switch (cat.self.value) {\n * case \"dead\":\n * return false;\n * case \"alive\":\n * return true;\n * }\n * }\n */\n abstract self: Left<A> | Right<B>;\n\n /**\n * Catch function with automatic conversion to Either<string, B>.\n * This version is used when no transformation function is provided.\n * It captures exceptions, converts them to a string, and wraps them in a Left.\n * If the operation is successful, the result is wrapped in a Right.\n *\n * @param fn - A function that might throw an error.\n * @returns {Either<string, B>} - Either an error message as a string or the successful result.\n *\n * @example\n * function gambleWithFailure() {\n * if (Math.random() > 0.5) {\n * throw \"Something went wrong\";\n * }\n * return \"Success\";\n * }\n *\n * const result = Either.catch(gambleWithFailure); // Left<string>(\"Something went wrong\") | Right<string>(\"Success\")\n */\n static catch<B>(fn: () => B): Either<string, B>;\n\n /**\n * Catch function with a custom transformation from unknown to A.\n * This version provides maximum flexibility, allowing any type of caught error to be transformed into type A.\n *\n * @param fn - A function that might throw an error.\n * @param liftE - A function that takes an unknown error and returns type A.\n * @returns {Either<A, B>} - Either the transformed error or the successful result.\n *\n * @example\n * function gambleWithFailure() {\n * if (Math.random() > 0.5) {\n * throw \"Something went wrong\";\n * }\n * return \"Success\";\n * }\n *\n * type MyError =\n * | \"GAMBLE_FAILED\"\n * | \"UNKNOWN_FAILURE\"\n *\n * const result2 = Either.catch(gambleWithFailure, (e: unknown): MyError => {\n * if (typeof e === \"string\") {\n * return \"GAMBLE_FAILED\";\n * } else {\n * return \"UNKNOWN_FAILURE\";\n * }\n * });\n */\n static catch<A, B>(fn: () => B, liftE: (e: unknown) => A): Either<A, B>;\n\n static catch<A, B>(fn: () => B, liftE?: (e: unknown) => A): Left<string> | Left<A> | Right<B> {\n try {\n return Right.pure(fn());\n } catch (e: unknown) {\n if (liftE) {\n return Left.pure(liftE(e));\n }\n\n const defaultLiftE = (e: unknown): string => {\n if (typeof e === \"string\") {\n return e;\n } else if (e && typeof (e as any).message === \"string\") {\n return (e as { message: string }).message;\n } else {\n return String(e);\n }\n };\n return Left.pure(defaultLiftE(e));\n }\n }\n\n /**\n * Transforms the right value of this Either by applying a function and returns a new Either.\n * @param f - A transformation function to apply to the right value.\n * @returns A new Either instance with the transformed value if this is a Right; otherwise, a Left.\n * @example\n * const result = Right.pure(5).map(x => x * 2); // Returns Right(10)\n */\n abstract map<C>(f: (right: B) => C): Either<A, C>;\n\n /**\n * Transforms the left value of this Either by applying a function and returns a new Either.\n * @param f - A transformation function to apply to the left value.\n * @returns A new Either instance with the transformed value if this is a Left; otherwise, a Right.\n * @example\n * const result = Left.pure(5).mapLeft(x => x * 2); // Returns Left(10)\n */\n abstract mapLeft<C>(f: (left: A) => C): Either<C, B>;\n\n /**\n * Applies a transformation function to the right value that returns an Either,\n * enabling chaining of operations that may fail.\n * @param f - A transformation function to apply that returns an Either.\n * @returns The result of the function if this is a Right; otherwise, a Left.\n * @example\n * const result = Right.pure(5).flatMap(x => Right.pure(x * 2)); // Returns Right(10)\n */\n abstract flatMap<C>(f: (right: B) => Either<A, C>): Either<A, C>;\n\n /**\n * Returns the value from this `Right` or the given argument if this is a `Left`.\n * @param value - A function that returns the default value.\n * @returns The value of `Right` or the result of `value`.\n * @example\n * Right.pure(5).getOrElse(() => 0); // Returns 5\n * Left.pure(\"error\").getOrElse(() => 0); // Returns 0\n */\n abstract getOrElse(value: (left: A) => B): B;\n\n /**\n * Returns the value from this `Right` or `null` if this is a `Left`.\n * @returns The value of `Right` or `null`.\n */\n abstract getOrNull(): B | null;\n\n /**\n * Swaps the `Left` and `Right` types.\n * @returns A new `Either` with the types swapped.\n */\n abstract swap(): Either<B, A>;\n\n /**\n * Applies one of two provided functions based on the contents of this Either.\n * @param ifLeft - A function to handle a Left value.\n * @param ifRight - A function to handle a Right value.\n * @returns The result of the applied function.\n * @example\n * const result = Right.pure(5).fold(\n * error => 'Error occurred',\n * value => 'Success with ' + value\n * ); // Returns 'Success with 5'\n */\n abstract fold<C>(ifLeft: (left: A) => C, ifRight: (right: B) => C): C;\n\n /**\n * Executes a provided function if this is a Right, used for side effects.\n * @param action - A function to execute with the right value.\n * @returns The original Either instance, facilitating method chaining.\n * @example\n * Right.pure(5).onRight(value => console.log(value)); // Logs \"5\"\n */\n abstract tap(action: (right: B) => void): Either<A, B>;\n\n /**\n * Executes a provided function if this is a Left, used for side effects.\n * @param action - A function to execute with the left value.\n * @returns The original Either instance, facilitating method chaining.\n * @example\n * Left.pure('Error').onLeft(err => console.log(err)); // Logs \"Error\"\n */\n abstract tapLeft(action: (left: A) => void): Either<A, B>;\n}\n\nexport class Left<A> extends Either<A, never> {\n readonly type = \"Left\" as const;\n\n self: Left<A> = this;\n\n private constructor(public readonly value: A) {\n super();\n }\n\n static pure<A>(value: A): Left<A> {\n return new Left<A>(value);\n }\n\n map<C>(_: (right: never) => C): Either<A, C> {\n return this;\n }\n\n mapLeft<C>(f: (left: A) => C): Either<C, never> {\n return new Left(f(this.value));\n }\n\n flatMap<C>(_: (right: never) => Either<A, C>): Either<A, C> {\n return this;\n }\n\n getOrElse(defaultValue: (left: A) => never): never {\n return defaultValue(this.value);\n }\n\n getOrNull(): null {\n return null;\n }\n\n swap(): Either<never, A> {\n return Right.pure(this.value);\n }\n\n fold<C>(ifLeft: (left: A) => C, _: (right: never) => C): C {\n return ifLeft(this.value);\n }\n\n tap(_: (right: never) => void): Either<A, never> {\n return this;\n }\n\n tapLeft(action: (left: A) => void): Either<A, never> {\n action(this.value);\n return this;\n }\n}\n\nexport class Right<B> extends Either<never, B> {\n readonly type = \"Right\" as const;\n\n self: Right<B> = this;\n\n private constructor(public readonly value: B) {\n super();\n }\n\n static pure<B>(value: B): Right<B> {\n return new Right<B>(value);\n }\n\n map<C>(f: (right: B) => C): Either<never, C> {\n return new Right<C>(f(this.value));\n }\n\n mapLeft<C>(_: (left: never) => C): Either<C, B> {\n return this;\n }\n\n flatMap<A, C>(f: (right: B) => Either<A, C>): Either<A, C> {\n return f(this.value);\n }\n\n getOrElse(_: (left: never) => B): B {\n return this.value;\n }\n\n getOrNull(): B {\n return this.value;\n }\n\n swap(): Either<B, never> {\n return Left.pure(this.value);\n }\n\n fold<C>(_: (left: never) => C, ifRight: (right: B) => C): C {\n return ifRight(this.value);\n }\n\n tap(action: (right: B) => void): Either<never, B> {\n action(this.value);\n return this;\n }\n\n tapLeft(_: (left: never) => void): Either<never, B> {\n return this;\n }\n}\n","/**\n * Throws a NotImplementedYet error indicating that a feature or functionality is not yet implemented.\n * This function is typically used as a placeholder for incomplete functionality.\n *\n * @throws {NotImplementedYetError} Throws a NotImplementedYet error with a message \"Not implemented yet\".\n * @returns {never} This function never returns as it always throws an error.\n *\n * @example\n * function someFunction() {\n * TODO();\n * }\n */\nexport function TODO(): never {\n throw new NotImplementedYetError(\"Not implemented yet\");\n}\n\n/**\n * Returns the input value without any modification. This function serves as an identity function,\n * returning the same value that is passed to it.\n *\n * @template A The type of the input value.\n * @param {A} a The input value.\n * @returns {A} The same value that was passed as input.\n *\n * @example\n * // Returns 5\n * identity(5);\n *\n * // Returns \"Hello\"\n * identity(\"Hello\");\n *\n * // Returns { x: 10, y: 20 }\n * identity({ x: 10, y: 20 });\n */\nexport function identity<A>(a: A): A {\n return a;\n}\n\n/**\n * Represents an error indicating that a feature or functionality is not yet implemented.\n * This error is typically thrown to indicate that a particular functionality is still pending development.\n *\n * @extends Error\n * @param {string} message The error message.\n * @property {string} name The name of the error, set to \"NotImplementedYetError\".\n *\n * @example\n * throw new NotImplementedYetError(\"Functionality not yet implemented.\");\n */\nexport class NotImplementedYetError extends Error {\n /**\n * Constructs a new NotImplementedYetError error with the provided message.\n * @param {string} message The error message.\n */\n constructor(message: string) {\n super(message);\n this.name = \"NotImplementedYetError\";\n }\n}\n","import { identity } from \"./utils\";\n\n/**\n * Represents an optional value. Every `Option<A>` is either `Some<A>` containing a value or `None` representing absence of value.\n * This interface supports operations like map, flatMap, and facilitates exhaustive type-checking through type narrowing.\n * @typeParam A - The type of the element contained within a `Some`.\n */\nexport abstract class Option<A> {\n abstract type: \"Some\" | \"None\";\n\n /**\n * Creates an Option instance from a value that may be null or undefined.\n * If the value is null or undefined, Option.None is returned.\n * Otherwise, Option.Some is returned with the given value.\n *\n * @template A The type of the value used to create an Option instance.\n * @param {A | null | undefined} value - The value to create the Option instance from.\n * @returns {Option<A>} - The created Option instance.\n * @example\n * const maybeNumber = Option.ofNullable(5); // Returns Some(5)\n * const maybeNull = Option.ofNullable(null); // Returns None\n */\n static ofNullable<A>(value: A | null | undefined): Option<NonNullable<A>> {\n return value === null || value === undefined ? None.Instance : Some.pure(value as NonNullable<A>);\n }\n\n /**\n * Lifts a non-null, non-undefined value into a `Some`. The companion to `Some.pure`, exposed on\n * the abstract class so users don't need to choose between `Some.pure` and `Option.ofNullable`\n * when they already know the value is present.\n *\n * For values that may be null or undefined, use {@link Option.ofNullable} instead.\n *\n * @template A The type of the value to lift.\n * @param {NonNullable<A>} value The value to wrap.\n * @returns {Option<NonNullable<A>>} `Some(value)`.\n *\n * @example\n * const opt = Option.pure(42); // Some(42)\n */\n static pure<A>(value: NonNullable<A>): Option<NonNullable<A>> {\n return Some.pure(value);\n }\n\n /**\n * Property to access the actual `Option` instance, enabling exhaustive type checking and type narrowing.\n * Use this when a switch statement needs to handle each subtype distinctly.\n *\n * @example\n * function getLength(text: Option<string>): number {\n * switch (text.self.type) {\n * case \"Some\":\n * // Type narrowing allows direct access to the `value`.\n * return text.self.value.length;\n * case \"None\":\n * return 0;\n * }\n * }\n */\n abstract self: None | Some<A>;\n\n /**\n * Transforms the `Option`'s value using a provided function, returning a new `Option` with the result.\n * If the `Option` is `None`, it returns `None`.\n * @example\n * const numberOption = Option.Some(5);\n * const incrementedOption = numberOption.map(x => x + 1); // Returns Some(6)\n */\n map<B>(f: (value: A) => B): Option<B> {\n return this.flatMap((value) => {\n const result = f(value);\n return result === null || result === undefined ? None.Instance : Some.pure(result as NonNullable<B>);\n });\n }\n\n /**\n * Applies a function that returns an `Option` to the `Option`'s value, if it exists, and flattens the result.\n * If the `Option` is `None`, it returns `None`.\n * @example\n * const numberOption = Option.Some(5);\n * const nestedOption = numberOption.flatMap(x => Option.Some(x + 1)); // Returns Some(6)\n */\n abstract flatMap<B>(f: (value: A) => Option<B>): Option<B>;\n\n /**\n * Returns this `Option` if it is a `Some` and the predicate returns `true`, otherwise returns `None`.\n * @param predicate - The predicate to test the value against.\n * @example\n * Option.Some(5).filter(x => x > 0); // Returns Some(5)\n * Option.Some(-5).filter(x => x > 0); // Returns None\n */\n abstract filter(predicate: (value: A) => boolean): Option<A>;\n\n /**\n * Executes a provided function if this `Option` is a `Some`, typically used for side effects.\n * Returns the original `Option` instance to facilitate method chaining.\n * @example\n * Option.Some(5).tap(value => console.log(value)); // Logs \"5\"\n * Option.None.tap(value => console.log(value)); // Does nothing\n */\n abstract tap(f: (value: A) => void): Option<A>;\n\n /**\n * Executes a provided function if this `Option` is a `None`, typically used for side effects.\n * Returns the original `Option` instance to facilitate method chaining.\n * @example\n * Option.Some(5).tapNone(() => console.log(\"No value\")); // Does nothing\n * Option.None.tapNone(() => console.log(\"No value\")); // Logs \"No value\"\n */\n abstract tapNone(f: () => void): Option<A>;\n\n /**\n * Applies one of two provided functions based on the contents of this `Option`.\n * If it is `None`, it applies `ifNone`. If it is `Some`, it applies `ifSome`.\n * @returns The result of the applied function.\n * @example\n * const result = Option.Some(5).fold(\n * () => 'No value',\n * value => 'Value is ' + value\n * ); // Returns 'Value is 5'\n */\n abstract fold<B>(ifNone: () => B, ifSome: (value: A) => B): B;\n\n /**\n * Returns the contained value if `Some`, otherwise returns `null`.\n * @example\n * const value = Option.Some(5).getOrNull(); // Returns 5\n * const empty = Option.None.getOrNull(); // Returns null\n */\n getOrNull(): A | null {\n return this.fold(() => null, identity);\n }\n\n /**\n * Returns the contained value if `Some`, otherwise returns the provided default value.\n * @example\n * const value = Option.Some(5).getOrElse(() => 10); // Returns 5\n * const empty = Option.None.getOrElse(() => 10); // Returns 10\n */\n getOrElse(defaultValue: () => A): A {\n return this.fold(() => defaultValue(), identity);\n }\n}\n\n/**\n * Represents an Option that contains no value.\n */\nexport class None extends Option<never> {\n readonly type = \"None\" as const;\n readonly self = this;\n private static readonly instance: None = new None();\n\n private constructor() {\n super();\n }\n\n /**\n * Returns the singleton instance of `None`.\n * @example\n * const emptyOption = None.Instance;\n */\n static get Instance() {\n return None.instance;\n }\n\n flatMap<B>(_: (value: never) => Option<B>): Option<B> {\n return this;\n }\n\n filter(_: (value: never) => boolean): Option<never> {\n return this;\n }\n\n fold<B>(ifNone: () => B, _: (right: never) => B): B {\n return ifNone();\n }\n\n getOrElse(defaultValue: () => never): never {\n return defaultValue();\n }\n\n getOrNull(): null {\n return null;\n }\n\n tap(_: (value: never) => void): Option<never> {\n return this;\n }\n\n tapNone(f: () => void): Option<never> {\n f();\n return this;\n }\n}\n\n/**\n * Represents an Option carrying a value.\n */\nexport class Some<A> extends Option<NonNullable<A>> {\n readonly type = \"Some\" as const;\n readonly self = this;\n\n private constructor(public readonly value: NonNullable<A>) {\n super();\n }\n\n /**\n * Creates a new `Some` instance containing the given value.\n * @param value - The value to wrap.\n * @returns A `Some` instance containing the value.\n * @example\n * const someOption = Some.pure(10);\n */\n static pure<A>(value: NonNullable<A>): Some<NonNullable<A>> {\n return new Some<NonNullable<A>>(value);\n }\n\n flatMap<B>(f: (value: NonNullable<A>) => Option<B>): Option<B> {\n return f(this.value);\n }\n\n filter(predicate: (value: NonNullable<A>) => boolean): Option<NonNullable<A>> {\n return predicate(this.value) ? this : None.Instance;\n }\n\n fold<B>(_: () => B, ifSome: (right: NonNullable<A>) => B): B {\n return ifSome(this.value);\n }\n\n getOrElse(_: () => NonNullable<A>): NonNullable<A> {\n return this.value;\n }\n\n getOrNull(): NonNullable<A> {\n return this.value;\n }\n\n tap(f: (value: NonNullable<A>) => void): Option<NonNullable<A>> {\n f(this.value);\n return this;\n }\n\n tapNone(_: () => void): Option<NonNullable<A>> {\n return this;\n }\n}\n","import { Either, Left, Right } from \"./either\";\nimport { IO } from \"./io\";\nimport { List } from \"./list\";\nimport { None, Option, Some } from \"./option\";\nimport { Ordering } from \"./ordering\";\n\nexport type Nel<A> = NonEmptyList<A>;\n\n/**\n * A list guaranteed to contain at least one element, paired with FP-style operations.\n *\n * `NonEmptyList<A>` is the refinement of {@link List} that statically guarantees a `head`.\n * Operations that preserve or guarantee non-emptiness (`map`, `flatMap`, `append`, `prepend`,\n * `concat`, `reverse`, `sort`, `distinct`, `intersperse`, `zipWithIndex`, `groupBy`, `chunk`,\n * and all `traverseX`) return `NonEmptyList`. Operations that may remove all elements\n * (`filter`, `filterNot`, `collect`, `partition`, `take`, `drop`, `takeWhile`, `dropWhile`,\n * `slice`) return `List<A>`.\n *\n * @template A The type of elements in the list.\n */\nexport class NonEmptyList<A> {\n /**\n * Constructs a new instance of `NonEmptyList` from a head and a tail list.\n * The head ensures the list is non-empty; the tail may be empty.\n *\n * @param {A} head The first element of the list.\n * @param {List<A>} tail The remaining elements, which may be empty.\n */\n constructor(\n public readonly head: A,\n public readonly tail: List<A>\n ) {}\n\n /**\n * Creates a `NonEmptyList` containing a single element.\n *\n * @template A The type of the element.\n * @param {A} value The single element.\n * @returns {NonEmptyList<A>} A `NonEmptyList` with one element and an empty tail.\n *\n * @example\n * const list = NonEmptyList.pure(42);\n * list.head; // 42\n * list.toArray(); // [42]\n * list.size; // 1\n */\n public static pure<A>(value: A): NonEmptyList<A> {\n return new NonEmptyList(value, List.empty<A>());\n }\n\n /**\n * Creates a `NonEmptyList` from an array. Returns `None` when the input is empty (or\n * null/undefined). Mirrors `list.toNel()` in the inverse direction.\n *\n * For statically-known non-empty input, prefer {@link NonEmptyList.of} which is total:\n * `NonEmptyList.of(1, 2, 3)`.\n *\n * @template A The type of elements in the list.\n * @param {readonly A[] | null | undefined} value The source array.\n * @returns {Option<NonEmptyList<A>>} `Some(nel)` if the array has at least one element,\n * `None` otherwise.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]); // Some(NonEmptyList [1, 2, 3])\n * NonEmptyList.fromArray([]); // None\n * NonEmptyList.fromArray(null); // None\n */\n public static fromArray<A>(value: readonly A[] | null | undefined): Option<NonEmptyList<A>> {\n if (!value || value.length === 0) return None.Instance as Option<NonEmptyList<A>>;\n return Some.pure(\n new NonEmptyList<A>(value[0], List._unsafeFromArray(value.slice(1))) as NonNullable<NonEmptyList<A>>\n ) as Option<NonEmptyList<A>>;\n }\n\n /**\n * Constructs a `NonEmptyList` from an array without the `Option` wrapper. The caller must\n * guarantee the array is non-empty; passing an empty array yields a malformed list that\n * will misbehave on access.\n *\n * Used internally by `IO`'s parallel combinators where non-emptiness is structurally\n * guaranteed (errors are collected only when at least one occurred). External code should\n * use {@link NonEmptyList.fromArray} (safe) or {@link NonEmptyList.of} (total) instead.\n *\n * @internal\n */\n public static _unsafeFromArray<A>(value: readonly A[]): NonEmptyList<A> {\n return new NonEmptyList<A>(value[0], List._unsafeFromArray(value.slice(1)));\n }\n\n /**\n * Builds a `NonEmptyList` from an explicit head and a variadic tail. The head argument\n * guarantees non-emptiness at the call site, so no runtime check is needed.\n *\n * @template A The type of elements.\n * @param {A} head The first element.\n * @param {...A[]} tail Additional elements.\n * @returns {NonEmptyList<A>} A new `NonEmptyList`.\n *\n * @example\n * NonEmptyList.of(1, 2, 3).toArray(); // [1, 2, 3]\n * NonEmptyList.of(\"hi\").toArray(); // [\"hi\"]\n */\n public static of<A>(head: A, ...tail: A[]): NonEmptyList<A> {\n return new NonEmptyList<A>(head, List._unsafeFromArray(tail));\n }\n\n /**\n * Returns the total number of elements in the `NonEmptyList`. Always `>= 1`.\n *\n * @returns {number} The total number of elements.\n */\n public get size(): number {\n return 1 + this.tail.size;\n }\n\n /**\n * Returns the last element of the `NonEmptyList`. Always total — never throws.\n *\n * @returns {A} The last element.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).last; // 3\n * NonEmptyList.pure(42).last; // 42\n */\n public get last(): A {\n return this.tail.isEmpty ? this.head : (this.tail.last as Some<A>).value;\n }\n\n /**\n * Returns all elements except the last as a {@link List}.\n * For a single-element list, returns the empty `List`.\n *\n * @returns {List<A>} A `List` of all elements except the last.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).init.toArray(); // [1, 2]\n * NonEmptyList.pure(1).init.toArray(); // []\n */\n public get init(): List<A> {\n if (this.tail.isEmpty) return List.empty();\n return List._unsafeFromArray([this.head, ...this.tail.toArray().slice(0, -1)]);\n }\n\n /**\n * Splits the `NonEmptyList` into its head and tail. Total — always returns a pair.\n *\n * @returns {[A, List<A>]} A tuple of `[head, tail]`.\n *\n * @example\n * const [h, t] = NonEmptyList.fromArray([1, 2, 3]).uncons;\n * h; // 1\n * t.toArray(); // [2, 3]\n */\n public get uncons(): [A, List<A>] {\n return [this.head, this.tail];\n }\n\n /**\n * Returns all elements as a plain array. The returned array is a fresh copy; later\n * mutations do not affect the `NonEmptyList`.\n *\n * @returns {A[]} An array containing all elements, starting with the head.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).toArray(); // [1, 2, 3]\n */\n public toArray(): A[] {\n return [this.head, ...this.tail.toArray()];\n }\n\n /**\n * Widens the `NonEmptyList` to a {@link List}. The returned `List` always has at least one\n * element, but the type system no longer tracks that guarantee.\n *\n * @returns {List<A>} A `List` view of the same elements.\n *\n * @example\n * const list = NonEmptyList.fromArray([1, 2, 3]).toList();\n * list.toArray(); // [1, 2, 3]\n */\n public toList(): List<A> {\n return List._unsafeFromArray(this.toArray());\n }\n\n /**\n * Retrieves the element at a specific zero-based index, where `0` corresponds to the head.\n * Out-of-bounds indices return `None`, matching {@link List.get}.\n *\n * @param {number} i The zero-based index of the element to retrieve.\n * @returns {Option<A>} `Some(element)` if in bounds, `None` otherwise.\n *\n * @example\n * NonEmptyList.fromArray([10, 20, 30]).get(0); // Some(10)\n * NonEmptyList.fromArray([10, 20, 30]).get(2); // Some(30)\n * NonEmptyList.fromArray([10, 20, 30]).get(99); // None\n * NonEmptyList.fromArray([10, 20, 30]).get(-1); // None\n */\n public get(i: number): Option<A> {\n if (i < 0 || i >= this.size) return None.Instance as Option<A>;\n if (i === 0) return Some.pure(this.head as NonNullable<A>) as Option<A>;\n return this.tail.get(i - 1);\n }\n\n /**\n * Applies a function to each element, producing a new `NonEmptyList` of the same length.\n *\n * @template B The type of elements in the resulting list.\n * @param {(value: A) => B} f A function applied to each element.\n * @returns {NonEmptyList<B>} A new `NonEmptyList` with the transformed elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).map(n => n * 2);\n * // NonEmptyList [2, 4, 6]\n */\n public map<B>(f: (value: A) => B): NonEmptyList<B> {\n return new NonEmptyList(f(this.head), this.tail.map(f));\n }\n\n /**\n * Applies a function that returns a `NonEmptyList` to each element, then flattens the\n * results. Because both the receiver and each result are non-empty, the result is too.\n *\n * @template B The type of elements in the resulting list.\n * @param {(value: A) => NonEmptyList<B>} f A function that maps each element to a `NonEmptyList`.\n * @returns {NonEmptyList<B>} A flattened `NonEmptyList` of the results.\n *\n * @example\n * NonEmptyList.fromArray([1, 2]).flatMap(n => NonEmptyList.of(n, n * 10));\n * // NonEmptyList [1, 10, 2, 20]\n */\n public flatMap<B>(f: (value: A) => NonEmptyList<B>): NonEmptyList<B> {\n const headResult = f(this.head);\n const tailArr: B[] = [];\n for (const x of this.tail.toArray()) {\n const sub = f(x);\n tailArr.push(sub.head, ...sub.tail.toArray());\n }\n return new NonEmptyList(headResult.head, List._unsafeFromArray([...headResult.tail.toArray(), ...tailArr]));\n }\n\n /**\n * Reduces the elements from left to right using an accumulator.\n *\n * @template B The type of the accumulator/result.\n * @param {B} start The initial accumulator value.\n * @param {(accumulator: B, value: A) => B} f A function that combines the accumulator with each element.\n * @returns {B} The final accumulated result.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).foldLeft(0, (acc, n) => acc + n); // 6\n */\n public foldLeft<B>(start: B, f: (accumulator: B, value: A) => B): B {\n return this.tail.foldLeft(f(start, this.head), f);\n }\n\n /**\n * Reduces the elements from right to left using an accumulator.\n *\n * @template B The type of the accumulator/result.\n * @param {B} start The initial accumulator value.\n * @param {(value: A, accumulator: B) => B} f A function that combines each element with the accumulator.\n * @returns {B} The final accumulated result.\n *\n * @example\n * NonEmptyList.fromArray([\"a\", \"b\", \"c\"]).foldRight(\"\", (s, acc) => acc + s); // \"cba\"\n */\n public foldRight<B>(start: B, f: (value: A, accumulator: B) => B): B {\n return f(this.head, this.tail.foldRight(start, f));\n }\n\n /**\n * Reduces the elements using a combining function, without requiring an initial value.\n * This is safe because the list is guaranteed to be non-empty.\n *\n * @param {(a: A, b: A) => A} f A function that combines two elements.\n * @returns {A} The result of reducing all elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).reduce((a, b) => a + b); // 6\n * NonEmptyList.pure(42).reduce((a, b) => a + b); // 42\n */\n public reduce(f: (a: A, b: A) => A): A {\n return this.tail.foldLeft(this.head, f);\n }\n\n /**\n * Executes `f` for each element, in order. Returns void.\n *\n * @param {(value: A) => void} f A function called once per element.\n *\n * @example\n * const out: number[] = [];\n * NonEmptyList.fromArray([1, 2, 3]).forEach(n => out.push(n));\n * // out: [1, 2, 3]\n */\n public forEach(f: (value: A) => void): void {\n f(this.head);\n this.tail.forEach(f);\n }\n\n /**\n * Counts the elements that satisfy the predicate.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {number} The number of matching elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4]).count(n => n % 2 === 0); // 2\n */\n public count(predicate: (value: A) => boolean): number {\n return (predicate(this.head) ? 1 : 0) + this.tail.count(predicate);\n }\n\n /**\n * Returns `true` if at least one element satisfies the predicate.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {boolean} `true` if any element matches, `false` otherwise.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).exists(n => n > 2); // true\n * NonEmptyList.fromArray([1, 2, 3]).exists(n => n > 5); // false\n */\n public exists(predicate: (value: A) => boolean): boolean {\n return predicate(this.head) || this.tail.exists(predicate);\n }\n\n /**\n * Returns `true` if all elements satisfy the predicate.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {boolean} `true` if every element matches, `false` otherwise.\n *\n * @example\n * NonEmptyList.fromArray([2, 4, 6]).forall(n => n % 2 === 0); // true\n * NonEmptyList.fromArray([2, 3, 6]).forall(n => n % 2 === 0); // false\n */\n public forall(predicate: (value: A) => boolean): boolean {\n return predicate(this.head) && this.tail.forall(predicate);\n }\n\n /**\n * Returns `true` if the list contains the given value. The optional `eq` function defaults\n * to `Object.is` semantics (so `NaN === NaN` and `+0 !== -0`).\n *\n * @param {A} value The value to look for.\n * @param {(a: A, b: A) => boolean} [eq=Object.is] Optional equality function.\n * @returns {boolean} `true` if a matching element exists.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).contains(2); // true\n * NonEmptyList.fromArray([1, 2, 3]).contains(99); // false\n */\n public contains(value: A, eq: (a: A, b: A) => boolean = Object.is): boolean {\n if (eq(this.head, value)) return true;\n return this.tail.contains(value, eq);\n }\n\n /**\n * Finds the first element that satisfies the predicate.\n *\n * @param {(value: A) => boolean} predicate A function that tests each element.\n * @returns {Option<A>} `Some(value)` if a matching element is found, `None` otherwise.\n *\n * @example\n * NonEmptyList.fromArray([1, 3, 4]).find(x => x % 2 === 0); // Some(4)\n * NonEmptyList.fromArray([1, 3, 5]).find(x => x > 10); // None\n */\n public find(predicate: (value: A) => boolean): Option<A> {\n if (predicate(this.head)) return Some.pure(this.head as NonNullable<A>) as Option<A>;\n return this.tail.find(predicate);\n }\n\n /**\n * Keeps elements satisfying the predicate. Because filtering may remove all elements, the\n * result is a {@link List}, not a `NonEmptyList`.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} A `List` of matching elements (possibly empty).\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4]).filter(n => n > 2).toArray(); // [3, 4]\n * NonEmptyList.fromArray([1, 2]).filter(n => n > 10).toArray(); // []\n */\n public filter(predicate: (value: A) => boolean): List<A> {\n const out: A[] = [];\n if (predicate(this.head)) out.push(this.head);\n for (const item of this.tail.toArray()) {\n if (predicate(item)) out.push(item);\n }\n return List._unsafeFromArray(out);\n }\n\n /**\n * Drops elements satisfying the predicate. Result is a {@link List} since filtering may\n * empty the list.\n *\n * @param {(value: A) => boolean} predicate A predicate; matching elements are removed.\n * @returns {List<A>} A `List` of non-matching elements (possibly empty).\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4]).filterNot(n => n > 2).toArray(); // [1, 2]\n */\n public filterNot(predicate: (value: A) => boolean): List<A> {\n return this.filter((x) => !predicate(x));\n }\n\n /**\n * Applies a partial function returning {@link Option} to each element, keeping only the\n * `Some` results.\n *\n * @template B The result element type.\n * @param {(value: A) => Option<B>} pf A partial function from `A` to `Option<B>`.\n * @returns {List<B>} A `List` of mapped, kept values (possibly empty).\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4])\n * .collect(n => n % 2 === 0 ? Some.pure(n * 10) : None.Instance)\n * .toArray(); // [20, 40]\n */\n public collect<B>(pf: (value: A) => Option<B>): List<B> {\n const out: B[] = [];\n const headR = pf(this.head);\n if (headR instanceof Some) out.push((headR as Some<B>).value);\n for (const item of this.tail.toArray()) {\n const r = pf(item);\n if (r instanceof Some) out.push((r as Some<B>).value);\n }\n return List._unsafeFromArray(out);\n }\n\n /**\n * Splits the list into two: elements matching the predicate, and those not matching.\n * Either side may be empty.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {[List<A>, List<A>]} A tuple of `[matching, nonMatching]`.\n *\n * @example\n * const [evens, odds] = NonEmptyList.fromArray([1, 2, 3, 4, 5]).partition(n => n % 2 === 0);\n * evens.toArray(); // [2, 4]\n * odds.toArray(); // [1, 3, 5]\n */\n public partition(predicate: (value: A) => boolean): [List<A>, List<A>] {\n return this.toList().partition(predicate);\n }\n\n /**\n * Returns a {@link List} of the first `n` elements (or all, if `n >= size`). Returns the\n * empty list when `n <= 0`.\n *\n * @param {number} n The number of elements to take.\n * @returns {List<A>} A `List` of up to `n` elements.\n */\n public take(n: number): List<A> {\n return this.toList().take(n);\n }\n\n /**\n * Returns a {@link List} of all elements after the first `n`. Returns the full list\n * when `n <= 0`, and the empty list when `n >= size`.\n *\n * @param {number} n The number of leading elements to drop.\n * @returns {List<A>} A `List` of remaining elements.\n */\n public drop(n: number): List<A> {\n return this.toList().drop(n);\n }\n\n /**\n * Returns the longest prefix of elements satisfying the predicate, as a {@link List}.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} The prefix of matching elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 1]).takeWhile(n => n < 3).toArray(); // [1, 2]\n */\n public takeWhile(predicate: (value: A) => boolean): List<A> {\n return this.toList().takeWhile(predicate);\n }\n\n /**\n * Drops the longest prefix of elements satisfying the predicate, returning the rest as a\n * {@link List}.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} The suffix of elements after the matching prefix.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 1]).dropWhile(n => n < 3).toArray(); // [3, 1]\n */\n public dropWhile(predicate: (value: A) => boolean): List<A> {\n return this.toList().dropWhile(predicate);\n }\n\n /**\n * Returns the slice `[from, to)` as a {@link List}. Indices are clamped to `[0, size]`.\n *\n * @param {number} from Inclusive start index.\n * @param {number} to Exclusive end index.\n * @returns {List<A>} A `List` of elements in the requested range.\n */\n public slice(from: number, to: number): List<A> {\n return this.toList().slice(from, to);\n }\n\n /**\n * Appends an element to the end, returning a new `NonEmptyList`.\n *\n * @param {A} value The element to append.\n * @returns {NonEmptyList<A>} A new list with the element at the end.\n *\n * @example\n * NonEmptyList.fromArray([1, 2]).append(3).toArray(); // [1, 2, 3]\n */\n public append(value: A): NonEmptyList<A> {\n return new NonEmptyList(this.head, List._unsafeFromArray([...this.tail.toArray(), value]));\n }\n\n /**\n * Prepends an element to the beginning, returning a new `NonEmptyList`.\n *\n * @param {A} value The element to place at the front.\n * @returns {NonEmptyList<A>} A new list with the element at the beginning.\n *\n * @example\n * NonEmptyList.fromArray([2, 3]).prepend(1).toArray(); // [1, 2, 3]\n */\n public prepend(value: A): NonEmptyList<A> {\n return new NonEmptyList(value, List._unsafeFromArray([this.head, ...this.tail.toArray()]));\n }\n\n /**\n * Concatenates with another `NonEmptyList`. Result remains non-empty.\n *\n * @param {NonEmptyList<A>} other The list to concatenate.\n * @returns {NonEmptyList<A>} A new list containing all elements of both.\n *\n * @example\n * const a = NonEmptyList.fromArray([1, 2]);\n * const b = NonEmptyList.fromArray([3, 4]);\n * a.concat(b).toArray(); // [1, 2, 3, 4]\n */\n public concat(other: NonEmptyList<A>): NonEmptyList<A>;\n /**\n * Concatenates with a possibly-empty {@link List}. Result remains non-empty since the\n * receiver is.\n *\n * @param {List<A>} other The list to concatenate.\n * @returns {NonEmptyList<A>} A new `NonEmptyList` containing all elements of both.\n *\n * @example\n * NonEmptyList.fromArray([1, 2]).concat(List.of(3, 4)).toArray(); // [1, 2, 3, 4]\n * NonEmptyList.fromArray([1, 2]).concat(List.empty<number>()).toArray(); // [1, 2]\n */\n public concat(other: List<A>): NonEmptyList<A>;\n public concat(other: List<A> | NonEmptyList<A>): NonEmptyList<A> {\n return new NonEmptyList(this.head, List._unsafeFromArray([...this.tail.toArray(), ...other.toArray()]));\n }\n\n /**\n * Reverses the order of elements, returning a new `NonEmptyList`.\n *\n * @returns {NonEmptyList<A>} A new list with elements in reverse order.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).reverse().toArray(); // [3, 2, 1]\n */\n public reverse(): NonEmptyList<A> {\n const arr = this.toArray().reverse();\n return new NonEmptyList(arr[0], List._unsafeFromArray(arr.slice(1)));\n }\n\n /**\n * Sorts the elements using an {@link Ordering}-returning comparator.\n *\n * @param {(a: A, b: A) => Ordering} comparator A function that compares two elements.\n * @returns {NonEmptyList<A>} A new sorted `NonEmptyList`.\n *\n * @example\n * NonEmptyList.fromArray([3, 1, 2]).sort((a, b) =>\n * a < b ? Ordering.LessThan : a > b ? Ordering.GreaterThan : Ordering.Equal\n * );\n * // NonEmptyList [1, 2, 3]\n */\n public sort(comparator: (a: A, b: A) => Ordering): NonEmptyList<A> {\n const sorted = this.toArray().sort((a, b) => comparator(a, b).value);\n return new NonEmptyList(sorted[0], List._unsafeFromArray(sorted.slice(1)));\n }\n\n /**\n * Sorts the elements by a key extracted from each element.\n *\n * @template K The key type.\n * @param {(value: A) => K} f Extracts the comparison key.\n * @param {(a: K, b: K) => Ordering} comparator Compares two keys.\n * @returns {NonEmptyList<A>} A new sorted `NonEmptyList`.\n *\n * @example\n * NonEmptyList.fromArray([{ id: 3 }, { id: 1 }])\n * .sortBy(u => u.id, (a, b) => a < b ? Ordering.LessThan : a > b ? Ordering.GreaterThan : Ordering.Equal);\n * // NonEmptyList [{ id: 1 }, { id: 3 }]\n */\n public sortBy<K>(f: (value: A) => K, comparator: (a: K, b: K) => Ordering): NonEmptyList<A> {\n const sorted = this.toArray().sort((a, b) => comparator(f(a), f(b)).value);\n return new NonEmptyList(sorted[0], List._unsafeFromArray(sorted.slice(1)));\n }\n\n /**\n * Removes duplicates, keeping the first occurrence of each value. Equality defaults to\n * `Object.is`. Result remains non-empty since the head always survives.\n *\n * @param {(a: A, b: A) => boolean} [eq=Object.is] Optional equality function.\n * @returns {NonEmptyList<A>} A new `NonEmptyList` with duplicates removed.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 1, 3, 2]).distinct().toArray(); // [1, 2, 3]\n */\n public distinct(eq: (a: A, b: A) => boolean = Object.is): NonEmptyList<A> {\n const arr = this.toList().distinct(eq).toArray();\n return new NonEmptyList(arr[0], List._unsafeFromArray(arr.slice(1)));\n }\n\n /**\n * Inserts `sep` between adjacent elements. For a single-element list this is a no-op.\n *\n * @param {A} sep The separator to interleave.\n * @returns {NonEmptyList<A>} A new `NonEmptyList` with `sep` between original elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).intersperse(0).toArray(); // [1, 0, 2, 0, 3]\n * NonEmptyList.pure(1).intersperse(0).toArray(); // [1]\n */\n public intersperse(sep: A): NonEmptyList<A> {\n if (this.tail.isEmpty) return this;\n const tailArr = this.tail.toArray();\n const out: A[] = [];\n for (let i = 0; i < tailArr.length; i++) {\n out.push(sep, tailArr[i]);\n }\n return new NonEmptyList(this.head, List._unsafeFromArray(out));\n }\n\n /**\n * Joins string representations of the elements using a separator.\n *\n * @param {string} [separator=\"\"] The string to place between elements.\n * @returns {string} The joined string.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).mkString(\", \"); // \"1, 2, 3\"\n * NonEmptyList.fromArray([\"a\", \"b\"]).mkString(\"-\"); // \"a-b\"\n */\n public mkString(separator: string = \"\"): string {\n return this.toArray().join(separator);\n }\n\n /**\n * Pairs elements with another `NonEmptyList`. Both being non-empty guarantees a non-empty\n * result.\n *\n * @template B The element type of the other list.\n * @param {NonEmptyList<B>} other The other list.\n * @returns {NonEmptyList<[A, B]>} A `NonEmptyList` of pairs.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).zip(NonEmptyList.fromArray([\"a\", \"b\", \"c\"])).toArray();\n * // [[1, \"a\"], [2, \"b\"], [3, \"c\"]]\n */\n public zip<B>(other: NonEmptyList<B>): NonEmptyList<[A, B]>;\n /**\n * Pairs elements with a possibly-empty {@link List}. If the other list is empty, the\n * result is empty.\n *\n * @template B The element type of the other list.\n * @param {List<B>} other The other list.\n * @returns {List<[A, B]>} A `List` of pairs (possibly empty).\n */\n public zip<B>(other: List<B>): List<[A, B]>;\n public zip<B>(other: List<B> | NonEmptyList<B>): List<[A, B]> | NonEmptyList<[A, B]> {\n if (other instanceof NonEmptyList) {\n const tailA = this.tail.toArray();\n const tailB = other.tail.toArray();\n const n = Math.min(tailA.length, tailB.length);\n const tail: [A, B][] = new Array(n);\n for (let i = 0; i < n; i++) tail[i] = [tailA[i], tailB[i]];\n return new NonEmptyList<[A, B]>([this.head, other.head], List._unsafeFromArray(tail));\n }\n return this.toList().zip(other);\n }\n\n /**\n * Combines paired elements via `f`. With another `NonEmptyList`, the result is non-empty.\n *\n * @template B The element type of the other list.\n * @template C The result element type.\n * @param {NonEmptyList<B>} other The other list.\n * @param {(a: A, b: B) => C} f Combines a pair of elements.\n * @returns {NonEmptyList<C>} A `NonEmptyList` of combined values.\n */\n public zipWith<B, C>(other: NonEmptyList<B>, f: (a: A, b: B) => C): NonEmptyList<C>;\n /**\n * Combines paired elements via `f`. Stops at the shorter list; may be empty.\n *\n * @template B The element type of the other list.\n * @template C The result element type.\n * @param {List<B>} other The other list.\n * @param {(a: A, b: B) => C} f Combines a pair of elements.\n * @returns {List<C>} A `List` of combined values.\n */\n public zipWith<B, C>(other: List<B>, f: (a: A, b: B) => C): List<C>;\n public zipWith<B, C>(other: List<B> | NonEmptyList<B>, f: (a: A, b: B) => C): List<C> | NonEmptyList<C> {\n if (other instanceof NonEmptyList) {\n const tailA = this.tail.toArray();\n const tailB = other.tail.toArray();\n const n = Math.min(tailA.length, tailB.length);\n const tail: C[] = new Array(n);\n for (let i = 0; i < n; i++) tail[i] = f(tailA[i], tailB[i]);\n return new NonEmptyList<C>(f(this.head, other.head), List._unsafeFromArray(tail));\n }\n return this.toList().zipWith(other, f);\n }\n\n /**\n * Pairs each element with its zero-based index. Result remains non-empty.\n *\n * @returns {NonEmptyList<[A, number]>} A `NonEmptyList` of `[element, index]` pairs.\n *\n * @example\n * NonEmptyList.fromArray([\"a\", \"b\", \"c\"]).zipWithIndex().toArray();\n * // [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n */\n public zipWithIndex(): NonEmptyList<[A, number]> {\n const tailArr = this.tail.toArray();\n const tail: [A, number][] = new Array(tailArr.length);\n for (let i = 0; i < tailArr.length; i++) tail[i] = [tailArr[i], i + 1];\n return new NonEmptyList<[A, number]>([this.head, 0], List._unsafeFromArray(tail));\n }\n\n /**\n * Groups elements by a key extracted via `f`. Iteration order in the resulting `Map`\n * reflects the order each key was first encountered. Each group is non-empty by\n * construction.\n *\n * @template K The key type.\n * @param {(value: A) => K} f Extracts the group key.\n * @returns {Map<K, NonEmptyList<A>>} A `Map` of group keys to their members.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4, 5]).groupBy(n => n % 2);\n * // Map { 1 => NEL[1, 3, 5], 0 => NEL[2, 4] }\n */\n public groupBy<K>(f: (value: A) => K): Map<K, NonEmptyList<A>> {\n return this.toList().groupBy(f);\n }\n\n /**\n * Splits the list into consecutive chunks of size `n`. The last chunk may be smaller. The\n * outer and inner lists are both `NonEmptyList`.\n *\n * @param {number} n The maximum chunk size; must be positive.\n * @returns {NonEmptyList<NonEmptyList<A>>} A non-empty list of non-empty chunks.\n * @throws {Error} If `n <= 0`.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4, 5]).chunk(2).toArray().map(c => c.toArray());\n * // [[1, 2], [3, 4], [5]]\n */\n public chunk(n: number): NonEmptyList<NonEmptyList<A>> {\n if (n <= 0) throw new Error(\"NonEmptyList.chunk size must be positive.\");\n const arr = this.toArray();\n const chunks: NonEmptyList<A>[] = [];\n for (let i = 0; i < arr.length; i += n) {\n const slice = arr.slice(i, i + n);\n chunks.push(new NonEmptyList(slice[0], List._unsafeFromArray(slice.slice(1))));\n }\n return new NonEmptyList(chunks[0], List._unsafeFromArray(chunks.slice(1)));\n }\n\n /**\n * Lifts a function `A => F<B>` over the list, producing `F<NonEmptyList<B>>` — where `F` is\n * one of the library's effect types. The first argument selects the effect; the return type\n * and evaluation strategy follow from it. Receiver is non-empty so the result is always\n * `F<NonEmptyList<B>>`.\n *\n * - `traverse(IO, f)` — sequential, fails fast on the first error (uses `IO`'s flatMap).\n * - `traverse(Either, f)` — short-circuits on the first `Left`.\n * - `traverse(Option, f)` — short-circuits on the first `None`.\n * - `traverse(Promise, f)` — parallel via `Promise.all`. For sequential async use\n * `traverse(IO, n => IO.lift(async () => …))` — IO is the proper sequential type.\n *\n * @example\n * await nel.traverse(IO, (n) => IO.lift(() => n * 10)).unsafeRun();\n * nel.traverse(Either, (n) => n > 0 ? Right.pure(n) : Left.pure(\"bad\"));\n * nel.traverse(Option, (n) => n > 0 ? Some.pure(n) : None.Instance);\n * await nel.traverse(Promise, async (n) => n * 2);\n */\n public traverse<E, B>(eff: typeof IO, f: (value: A) => IO<E, B>): IO<E, NonEmptyList<B>>;\n public traverse<L, B>(eff: typeof Either, f: (value: A) => Either<L, B>): Either<L, NonEmptyList<B>>;\n public traverse<B>(eff: typeof Option, f: (value: A) => Option<B>): Option<NonEmptyList<B>>;\n public traverse<B>(eff: PromiseConstructor, f: (value: A) => Promise<B>): Promise<NonEmptyList<B>>;\n public traverse(eff: unknown, f: (value: A) => unknown): unknown {\n if (eff === IO) {\n return IO.traverse(this.toArray(), f as (a: A) => IO<unknown, unknown>).map((list) =>\n NonEmptyList._unsafeFromArray(list.toArray())\n );\n }\n if (eff === Either) {\n const headR = f(this.head);\n if (headR instanceof Left) return headR;\n const tailOut: unknown[] = [];\n for (const item of this.tail.toArray()) {\n const r = f(item);\n if (r instanceof Left) return r;\n tailOut.push((r as Right<unknown>).value);\n }\n return Right.pure(new NonEmptyList((headR as Right<unknown>).value, List._unsafeFromArray(tailOut)));\n }\n if (eff === Option) {\n const headR = f(this.head);\n if (!(headR instanceof Some)) return None.Instance;\n const tailOut: unknown[] = [];\n for (const item of this.tail.toArray()) {\n const r = f(item);\n if (!(r instanceof Some)) return None.Instance;\n tailOut.push((r as Some<unknown>).value);\n }\n return Some.pure(\n new NonEmptyList((headR as Some<unknown>).value, List._unsafeFromArray(tailOut)) as NonNullable<\n NonEmptyList<unknown>\n >\n );\n }\n if (eff === Promise) {\n const fn = f as (a: A) => Promise<unknown>;\n return Promise.all([fn(this.head), ...this.tail.toArray().map(fn)]).then(\n ([headResult, ...tailResults]) => new NonEmptyList(headResult, List._unsafeFromArray(tailResults))\n );\n }\n throw new Error(\n `NonEmptyList.traverse: unknown effect type — expected IO, Either, Option, or Promise, got ${String(eff)}`\n );\n }\n\n /**\n * Returns a string representation of the `NonEmptyList`.\n *\n * @returns {string} A string showing all elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).toString(); // \"[1, 2, 3]\"\n */\n public toString(): string {\n return `[${this.toArray().join(\", \")}]`;\n }\n}\n","import { Either, Left, Right } from \"./either\";\nimport { IO } from \"./io\";\nimport { NonEmptyList } from \"./non-empty-list\";\nimport { None, Option, Some } from \"./option\";\nimport { Ordering } from \"./ordering\";\n\n/**\n * An immutable, possibly-empty list with FP-style operations.\n *\n * `List<A>` is the general-purpose counterpart to {@link NonEmptyList}. Operations that may\n * remove all elements (`filter`, `filterNot`, `collect`, `partition`, `take`, `drop`,\n * `takeWhile`, `dropWhile`, `slice`) return `List<A>`. Operations that preserve or guarantee\n * non-emptiness (`append`, `prepend`, `concat` with a `NonEmptyList`) return `NonEmptyList<A>`.\n *\n * Instances are immutable; every operation returns a new instance. The backing array is\n * defensively copied on construction so user-supplied arrays can be mutated freely afterwards.\n *\n * @template A The type of elements in the list.\n */\nexport class List<A> {\n private constructor(private readonly _items: readonly A[]) {}\n\n /**\n * Constructs a `List` without copying the input array. The caller must guarantee that the\n * passed array will not be mutated. This is used internally by {@link NonEmptyList} and the\n * library's traverse implementations to avoid redundant allocations.\n *\n * @internal\n */\n public static _unsafeFromArray<A>(values: readonly A[]): List<A> {\n return new List<A>(values);\n }\n\n /**\n * Returns the empty `List`.\n *\n * @template A The element type.\n * @returns {List<A>} An empty `List<A>`.\n *\n * @example\n * List.empty<number>().isEmpty; // true\n */\n public static empty<A>(): List<A> {\n return new List<A>([]);\n }\n\n /**\n * Creates a `List` with a single element.\n *\n * @template A The element type.\n * @param {A} value The single element.\n * @returns {List<A>} A `List` containing exactly `value`.\n *\n * @example\n * List.pure(42).toArray(); // [42]\n */\n public static pure<A>(value: A): List<A> {\n return new List<A>([value]);\n }\n\n /**\n * Creates a `List` from a variadic argument list.\n *\n * @template A The element type.\n * @param {...A[]} values The elements, in order.\n * @returns {List<A>} A `List` containing the given elements.\n *\n * @example\n * List.of(1, 2, 3).toArray(); // [1, 2, 3]\n * List.of<number>().toArray(); // []\n */\n public static of<A>(...values: A[]): List<A> {\n return new List<A>(values.slice());\n }\n\n /**\n * Creates a `List` from an array. The input is copied; later mutations to the source array\n * do not affect the resulting `List`.\n *\n * @template A The element type.\n * @param {readonly A[]} values The source array.\n * @returns {List<A>} A `List` containing a copy of the array's elements.\n *\n * @example\n * const arr = [1, 2, 3];\n * const l = List.fromArray(arr);\n * arr.push(4);\n * l.toArray(); // [1, 2, 3] — unaffected\n */\n public static fromArray<A>(values: readonly A[]): List<A> {\n return new List<A>(values.slice());\n }\n\n /**\n * Widens a {@link NonEmptyList} to a `List`. Equivalent to `nel.toList()`.\n *\n * @template A The element type.\n * @param {NonEmptyList<A>} nel The non-empty list.\n * @returns {List<A>} A `List` view of the same elements.\n *\n * @example\n * List.fromNel(NonEmptyList.fromArray([1, 2, 3])).toArray(); // [1, 2, 3]\n */\n public static fromNel<A>(nel: NonEmptyList<A>): List<A> {\n return new List<A>(nel.toArray());\n }\n\n /**\n * Creates a `List` of integers from `start` (inclusive) to `endExclusive`, stepping by `step`.\n *\n * If `step > 0` and `endExclusive <= start`, or `step < 0` and `endExclusive >= start`,\n * returns the empty list.\n *\n * @param {number} start The first value.\n * @param {number} endExclusive The exclusive end value.\n * @param {number} [step=1] The increment between successive values. Must be non-zero.\n * @returns {List<number>} A `List<number>` of the requested range.\n * @throws {Error} If `step` is zero.\n *\n * @example\n * List.range(0, 5).toArray(); // [0, 1, 2, 3, 4]\n * List.range(0, 10, 2).toArray(); // [0, 2, 4, 6, 8]\n * List.range(5, 0, -1).toArray(); // [5, 4, 3, 2, 1]\n * List.range(5, 5).toArray(); // []\n */\n public static range(start: number, endExclusive: number, step: number = 1): List<number> {\n if (step === 0) throw new Error(\"List.range step must be non-zero.\");\n const out: number[] = [];\n if (step > 0) {\n for (let i = start; i < endExclusive; i += step) out.push(i);\n } else {\n for (let i = start; i > endExclusive; i += step) out.push(i);\n }\n return new List(out);\n }\n\n /**\n * Creates a `List` of length `n` where every element is `value`. Returns the empty list\n * when `n <= 0`.\n *\n * @template A The element type.\n * @param {number} n The number of repetitions.\n * @param {A} value The value to repeat.\n * @returns {List<A>} A `List` of `n` copies of `value`.\n *\n * @example\n * List.fill(3, \"x\").toArray(); // [\"x\", \"x\", \"x\"]\n * List.fill(0, \"x\").toArray(); // []\n */\n public static fill<A>(n: number, value: A): List<A> {\n if (n <= 0) return List.empty();\n return new List<A>(new Array(n).fill(value));\n }\n\n /**\n * The number of elements in the `List`.\n *\n * @returns {number} The element count.\n */\n public get size(): number {\n return this._items.length;\n }\n\n /**\n * `true` if the `List` has no elements.\n *\n * @returns {boolean} Whether the list is empty.\n */\n public get isEmpty(): boolean {\n return this._items.length === 0;\n }\n\n /**\n * `true` if the `List` has at least one element. Equivalent to `!isEmpty`.\n *\n * @returns {boolean} Whether the list has at least one element.\n */\n public get nonEmpty(): boolean {\n return this._items.length > 0;\n }\n\n /**\n * The first element wrapped in {@link Option}.\n *\n * @returns {Option<A>} `Some(head)` if non-empty, `None` otherwise.\n *\n * @example\n * List.of(1, 2, 3).head; // Some(1)\n * List.empty<number>().head; // None\n */\n public get head(): Option<A> {\n return this._items.length === 0\n ? (None.Instance as Option<A>)\n : (Some.pure(this._items[0] as NonNullable<A>) as Option<A>);\n }\n\n /**\n * The last element wrapped in {@link Option}.\n *\n * @returns {Option<A>} `Some(last)` if non-empty, `None` otherwise.\n *\n * @example\n * List.of(1, 2, 3).last; // Some(3)\n * List.empty<number>().last; // None\n */\n public get last(): Option<A> {\n return this._items.length === 0\n ? (None.Instance as Option<A>)\n : (Some.pure(this._items[this._items.length - 1] as NonNullable<A>) as Option<A>);\n }\n\n /**\n * All elements except the first, as a new `List`. Returns the empty list when the list has\n * 0 or 1 elements.\n *\n * @returns {List<A>} The tail of the list.\n *\n * @example\n * List.of(1, 2, 3).tail.toArray(); // [2, 3]\n * List.of(1).tail.toArray(); // []\n * List.empty<number>().tail.toArray(); // []\n */\n public get tail(): List<A> {\n return this._items.length <= 1 ? List.empty() : new List(this._items.slice(1));\n }\n\n /**\n * All elements except the last, as a new `List`. Returns the empty list when the list has\n * 0 or 1 elements.\n *\n * @returns {List<A>} All elements except the last.\n *\n * @example\n * List.of(1, 2, 3).init.toArray(); // [1, 2]\n * List.of(1).init.toArray(); // []\n */\n public get init(): List<A> {\n return this._items.length <= 1 ? List.empty() : new List(this._items.slice(0, -1));\n }\n\n /**\n * Splits the list into its head and tail.\n *\n * @returns {Option<[A, List<A>]>} `Some([head, tail])` if non-empty, `None` otherwise.\n *\n * @example\n * const opt = List.of(1, 2, 3).uncons; // Some([1, List [2, 3]])\n * List.empty<number>().uncons; // None\n */\n public get uncons(): Option<[A, List<A>]> {\n if (this._items.length === 0) return None.Instance as Option<[A, List<A>]>;\n const tuple: [A, List<A>] = [this._items[0], new List(this._items.slice(1))];\n return Some.pure(tuple as NonNullable<[A, List<A>]>) as Option<[A, List<A>]>;\n }\n\n /**\n * Returns the element at index `i` wrapped in {@link Option}. Out-of-bounds indices yield\n * `None` rather than throwing.\n *\n * @param {number} i Zero-based index.\n * @returns {Option<A>} `Some(element)` if in bounds, `None` otherwise.\n *\n * @example\n * List.of(10, 20, 30).get(1); // Some(20)\n * List.of(10, 20, 30).get(99); // None\n * List.of(10, 20, 30).get(-1); // None\n */\n public get(i: number): Option<A> {\n if (i < 0 || i >= this._items.length) return None.Instance as Option<A>;\n return Some.pure(this._items[i] as NonNullable<A>) as Option<A>;\n }\n\n /**\n * Returns a fresh array copy of the elements.\n *\n * @returns {A[]} A new array containing all elements.\n *\n * @example\n * List.of(1, 2, 3).toArray(); // [1, 2, 3]\n */\n public toArray(): A[] {\n return this._items.slice();\n }\n\n /**\n * Narrows to a {@link NonEmptyList}.\n *\n * @returns {Option<NonEmptyList<A>>} `Some(nel)` if non-empty, `None` otherwise.\n *\n * @example\n * List.of(1, 2, 3).toNel(); // Some(NonEmptyList [1, 2, 3])\n * List.empty<number>().toNel(); // None\n */\n public toNel(): Option<NonEmptyList<A>> {\n if (this._items.length === 0) return None.Instance as Option<NonEmptyList<A>>;\n return Some.pure(\n new NonEmptyList<A>(this._items[0], new List(this._items.slice(1))) as NonNullable<NonEmptyList<A>>\n ) as Option<NonEmptyList<A>>;\n }\n\n /**\n * Applies a function to each element, producing a new `List` of the same length.\n *\n * @template B The result element type.\n * @param {(value: A) => B} f A function applied to each element.\n * @returns {List<B>} A new `List` with the transformed elements.\n *\n * @example\n * List.of(1, 2, 3).map(n => n * 2).toArray(); // [2, 4, 6]\n */\n public map<B>(f: (value: A) => B): List<B> {\n return new List(this._items.map(f));\n }\n\n /**\n * Maps each element to a `List` and concatenates the results.\n *\n * @template B The result element type.\n * @param {(value: A) => List<B>} f A function producing a `List` for each element.\n * @returns {List<B>} A flattened `List` of the results.\n *\n * @example\n * List.of(1, 2, 3).flatMap(n => List.of(n, n * 10)).toArray();\n * // [1, 10, 2, 20, 3, 30]\n */\n public flatMap<B>(f: (value: A) => List<B>): List<B> {\n const out: B[] = [];\n for (const item of this._items) {\n for (const b of f(item)._items) out.push(b);\n }\n return new List(out);\n }\n\n /**\n * Flattens a `List<List<B>>` by one level. Empty inner lists are silently dropped.\n *\n * @template B The inner element type.\n * @returns {List<B>} A flattened `List`.\n *\n * @example\n * List.of(List.of(1, 2), List.empty<number>(), List.of(3)).flatten().toArray();\n * // [1, 2, 3]\n */\n public flatten<B>(this: List<List<B>>): List<B> {\n return this.flatMap((x) => x);\n }\n\n /**\n * Reduces the elements from left to right using an accumulator.\n *\n * @template B The accumulator/result type.\n * @param {B} start The initial accumulator value.\n * @param {(accumulator: B, value: A) => B} f Combines the accumulator with each element.\n * @returns {B} The final accumulated result. Returns `start` for the empty list.\n *\n * @example\n * List.of(1, 2, 3).foldLeft(0, (acc, n) => acc + n); // 6\n * List.empty<number>().foldLeft(7, (acc, n) => acc + n); // 7\n */\n public foldLeft<B>(start: B, f: (accumulator: B, value: A) => B): B {\n return this._items.reduce(f, start);\n }\n\n /**\n * Reduces the elements from right to left using an accumulator.\n *\n * @template B The accumulator/result type.\n * @param {B} start The initial accumulator value.\n * @param {(value: A, accumulator: B) => B} f Combines each element with the accumulator.\n * @returns {B} The final accumulated result. Returns `start` for the empty list.\n *\n * @example\n * List.of(\"a\", \"b\", \"c\").foldRight(\"\", (v, acc) => acc + v); // \"cba\"\n */\n public foldRight<B>(start: B, f: (value: A, accumulator: B) => B): B {\n return this._items.reduceRight((acc, v) => f(v, acc), start);\n }\n\n /**\n * Combines elements pairwise without an initial value. Returns `None` for the empty list,\n * which is why the return type is `Option<A>` (unlike `NonEmptyList#reduce`, which is total).\n *\n * @param {(a: A, b: A) => A} f Combines two elements.\n * @returns {Option<A>} `Some(result)` if non-empty, `None` otherwise.\n *\n * @example\n * List.of(1, 2, 3).reduce((a, b) => a + b); // Some(6)\n * List.empty<number>().reduce((a, b) => a + b); // None\n */\n public reduce(f: (a: A, b: A) => A): Option<A> {\n if (this._items.length === 0) return None.Instance as Option<A>;\n let acc = this._items[0];\n for (let i = 1; i < this._items.length; i++) acc = f(acc, this._items[i]);\n return Some.pure(acc as NonNullable<A>) as Option<A>;\n }\n\n /**\n * Executes `f` for each element, in order. Returns void.\n *\n * @param {(value: A) => void} f A function called once per element.\n *\n * @example\n * const out: number[] = [];\n * List.of(1, 2, 3).forEach(n => out.push(n));\n * // out: [1, 2, 3]\n */\n public forEach(f: (value: A) => void): void {\n for (const item of this._items) f(item);\n }\n\n /**\n * Counts the elements that satisfy the predicate.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {number} The number of matching elements.\n *\n * @example\n * List.of(1, 2, 3, 4).count(n => n % 2 === 0); // 2\n */\n public count(predicate: (value: A) => boolean): number {\n let n = 0;\n for (const item of this._items) if (predicate(item)) n++;\n return n;\n }\n\n /**\n * Returns `true` if at least one element satisfies the predicate.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {boolean} `true` if any element matches, `false` otherwise (including the empty list).\n *\n * @example\n * List.of(1, 2, 3).exists(n => n > 2); // true\n * List.empty<number>().exists(n => n > 0); // false\n */\n public exists(predicate: (value: A) => boolean): boolean {\n return this._items.some(predicate);\n }\n\n /**\n * Returns `true` if every element satisfies the predicate. Vacuously `true` for the empty\n * list.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {boolean} `true` if every element matches.\n *\n * @example\n * List.of(2, 4, 6).forall(n => n % 2 === 0); // true\n * List.of(2, 3, 6).forall(n => n % 2 === 0); // false\n * List.empty<number>().forall(n => false); // true (vacuous)\n */\n public forall(predicate: (value: A) => boolean): boolean {\n return this._items.every(predicate);\n }\n\n /**\n * Returns `true` if the list contains the given value. The optional `eq` function defaults\n * to `Object.is` semantics (so `NaN === NaN` and `+0 !== -0`).\n *\n * @param {A} value The value to look for.\n * @param {(a: A, b: A) => boolean} [eq=Object.is] Optional equality function.\n * @returns {boolean} `true` if a matching element exists.\n *\n * @example\n * List.of(1, 2, 3).contains(2); // true\n * List.of(1, 2, 3).contains(99); // false\n */\n public contains(value: A, eq: (a: A, b: A) => boolean = Object.is): boolean {\n for (const item of this._items) if (eq(item, value)) return true;\n return false;\n }\n\n /**\n * Finds the first element that satisfies the predicate.\n *\n * @param {(value: A) => boolean} predicate A function that tests each element.\n * @returns {Option<A>} `Some(value)` if a match is found, `None` otherwise.\n *\n * @example\n * List.of(1, 3, 4).find(x => x % 2 === 0); // Some(4)\n * List.of(1, 3, 5).find(x => x > 10); // None\n */\n public find(predicate: (value: A) => boolean): Option<A> {\n const i = this._items.findIndex(predicate);\n if (i === -1) return None.Instance as Option<A>;\n return Some.pure(this._items[i] as NonNullable<A>) as Option<A>;\n }\n\n /**\n * Finds the index of the first element satisfying the predicate.\n *\n * @param {(value: A) => boolean} predicate A function that tests each element.\n * @returns {Option<number>} `Some(index)` if a match is found, `None` otherwise.\n *\n * @example\n * List.of(10, 20, 30).findIndex(n => n === 20); // Some(1)\n * List.of(10, 20).findIndex(n => n === 99); // None\n */\n public findIndex(predicate: (value: A) => boolean): Option<number> {\n const i = this._items.findIndex(predicate);\n if (i === -1) return None.Instance as Option<number>;\n return Some.pure(i as NonNullable<number>) as Option<number>;\n }\n\n /**\n * Keeps the elements satisfying the predicate.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} A `List` of matching elements (possibly empty).\n *\n * @example\n * List.of(1, 2, 3, 4).filter(n => n % 2 === 0).toArray(); // [2, 4]\n */\n public filter(predicate: (value: A) => boolean): List<A> {\n return new List(this._items.filter(predicate));\n }\n\n /**\n * Drops the elements satisfying the predicate.\n *\n * @param {(value: A) => boolean} predicate A predicate; matching elements are removed.\n * @returns {List<A>} A `List` of non-matching elements (possibly empty).\n *\n * @example\n * List.of(1, 2, 3, 4).filterNot(n => n % 2 === 0).toArray(); // [1, 3]\n */\n public filterNot(predicate: (value: A) => boolean): List<A> {\n return new List(this._items.filter((x) => !predicate(x)));\n }\n\n /**\n * Applies a partial function returning {@link Option} to each element, keeping only the\n * `Some` results. This is the standard \"filter and map at once\" pattern.\n *\n * @template B The result element type.\n * @param {(value: A) => Option<B>} pf A partial function from `A` to `Option<B>`.\n * @returns {List<B>} A `List` of mapped, kept values (possibly empty).\n *\n * @example\n * List.of(1, 2, 3, 4)\n * .collect(n => n % 2 === 0 ? Some.pure(n * 10) : None.Instance)\n * .toArray();\n * // [20, 40]\n */\n public collect<B>(pf: (value: A) => Option<B>): List<B> {\n const out: B[] = [];\n for (const item of this._items) {\n const r = pf(item);\n if (r instanceof Some) out.push((r as Some<B>).value);\n }\n return new List(out);\n }\n\n /**\n * Splits the list into matching and non-matching elements.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {[List<A>, List<A>]} A tuple of `[matching, nonMatching]`.\n *\n * @example\n * const [evens, odds] = List.of(1, 2, 3, 4, 5).partition(n => n % 2 === 0);\n * evens.toArray(); // [2, 4]\n * odds.toArray(); // [1, 3, 5]\n */\n public partition(predicate: (value: A) => boolean): [List<A>, List<A>] {\n const yes: A[] = [];\n const no: A[] = [];\n for (const item of this._items) (predicate(item) ? yes : no).push(item);\n return [new List(yes), new List(no)];\n }\n\n /**\n * Returns the first `n` elements. Returns the empty list when `n <= 0`, or the whole list\n * when `n >= size`.\n *\n * @param {number} n The number of elements to take.\n * @returns {List<A>} A `List` of up to `n` elements.\n *\n * @example\n * List.of(1, 2, 3, 4).take(2).toArray(); // [1, 2]\n * List.of(1, 2, 3, 4).take(99).toArray(); // [1, 2, 3, 4]\n */\n public take(n: number): List<A> {\n if (n <= 0) return List.empty();\n return new List(this._items.slice(0, n));\n }\n\n /**\n * Returns all elements after the first `n`. Returns the whole list when `n <= 0`, or the\n * empty list when `n >= size`.\n *\n * @param {number} n The number of leading elements to drop.\n * @returns {List<A>} A `List` of remaining elements.\n *\n * @example\n * List.of(1, 2, 3, 4).drop(2).toArray(); // [3, 4]\n * List.of(1, 2, 3, 4).drop(99).toArray(); // []\n */\n public drop(n: number): List<A> {\n if (n <= 0) return new List(this._items.slice());\n return new List(this._items.slice(n));\n }\n\n /**\n * Returns the longest prefix of elements satisfying the predicate.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} The matching prefix.\n *\n * @example\n * List.of(1, 2, 3, 1).takeWhile(n => n < 3).toArray(); // [1, 2]\n */\n public takeWhile(predicate: (value: A) => boolean): List<A> {\n const out: A[] = [];\n for (const item of this._items) {\n if (!predicate(item)) break;\n out.push(item);\n }\n return new List(out);\n }\n\n /**\n * Drops the longest prefix of elements satisfying the predicate, returning the rest.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} The suffix after the matching prefix.\n *\n * @example\n * List.of(1, 2, 3, 1).dropWhile(n => n < 3).toArray(); // [3, 1]\n */\n public dropWhile(predicate: (value: A) => boolean): List<A> {\n let i = 0;\n while (i < this._items.length && predicate(this._items[i])) i++;\n return new List(this._items.slice(i));\n }\n\n /**\n * Returns the slice `[from, to)`. Indices are clamped to `[0, size]`.\n *\n * @param {number} from Inclusive start index.\n * @param {number} to Exclusive end index.\n * @returns {List<A>} A `List` of elements in the requested range.\n *\n * @example\n * List.of(0, 1, 2, 3, 4).slice(1, 4).toArray(); // [1, 2, 3]\n * List.of(0, 1, 2).slice(-5, 99).toArray(); // [0, 1, 2]\n */\n public slice(from: number, to: number): List<A> {\n return new List(this._items.slice(Math.max(0, from), Math.max(0, to)));\n }\n\n /**\n * Appends an element to the end. The result is guaranteed non-empty, so the return type is\n * {@link NonEmptyList}.\n *\n * @param {A} value The element to append.\n * @returns {NonEmptyList<A>} A new `NonEmptyList` with `value` at the end.\n *\n * @example\n * List.empty<number>().append(1).toArray(); // [1]\n * List.of(1, 2).append(3).toArray(); // [1, 2, 3]\n */\n public append(value: A): NonEmptyList<A> {\n if (this._items.length === 0) return new NonEmptyList(value, List.empty<A>());\n return new NonEmptyList(this._items[0], new List([...this._items.slice(1), value]));\n }\n\n /**\n * Prepends an element to the beginning. The result is guaranteed non-empty, so the return\n * type is {@link NonEmptyList}.\n *\n * @param {A} value The element to place at the front.\n * @returns {NonEmptyList<A>} A new `NonEmptyList` with `value` at the front.\n *\n * @example\n * List.of(2, 3).prepend(1).toArray(); // [1, 2, 3]\n */\n public prepend(value: A): NonEmptyList<A> {\n return new NonEmptyList(value, new List(this._items.slice()));\n }\n\n /**\n * Concatenates with a {@link NonEmptyList}. Result is non-empty.\n *\n * @param {NonEmptyList<A>} other The non-empty list to concatenate.\n * @returns {NonEmptyList<A>} A `NonEmptyList` containing all elements of both.\n *\n * @example\n * List.empty<number>().concat(NonEmptyList.fromArray([1, 2])).toArray(); // [1, 2]\n */\n public concat(other: NonEmptyList<A>): NonEmptyList<A>;\n /**\n * Concatenates with another `List`. The result is empty only if both sides are empty.\n *\n * @param {List<A>} other The list to concatenate.\n * @returns {List<A>} A `List` containing all elements of both.\n *\n * @example\n * List.of(1, 2).concat(List.of(3, 4)).toArray(); // [1, 2, 3, 4]\n */\n public concat(other: List<A>): List<A>;\n public concat(other: List<A> | NonEmptyList<A>): List<A> | NonEmptyList<A> {\n if (other instanceof NonEmptyList) {\n const otherArr = other.toArray();\n if (this._items.length === 0) {\n return new NonEmptyList(otherArr[0], new List(otherArr.slice(1)));\n }\n return new NonEmptyList(this._items[0], new List([...this._items.slice(1), ...otherArr]));\n }\n return new List([...this._items, ...other._items]);\n }\n\n /**\n * Reverses the order of elements.\n *\n * @returns {List<A>} A new `List` with elements in reverse order.\n *\n * @example\n * List.of(1, 2, 3).reverse().toArray(); // [3, 2, 1]\n */\n public reverse(): List<A> {\n return new List(this._items.slice().reverse());\n }\n\n /**\n * Sorts using an {@link Ordering}-returning comparator.\n *\n * @param {(a: A, b: A) => Ordering} comparator A function that compares two elements.\n * @returns {List<A>} A new sorted `List`.\n *\n * @example\n * List.of(3, 1, 2).sort((a, b) =>\n * a < b ? Ordering.LessThan : a > b ? Ordering.GreaterThan : Ordering.Equal\n * ).toArray();\n * // [1, 2, 3]\n */\n public sort(comparator: (a: A, b: A) => Ordering): List<A> {\n return new List(this._items.slice().sort((a, b) => comparator(a, b).value));\n }\n\n /**\n * Sorts by a key extracted from each element.\n *\n * @template K The key type.\n * @param {(value: A) => K} f Extracts the comparison key.\n * @param {(a: K, b: K) => Ordering} comparator Compares two keys.\n * @returns {List<A>} A new sorted `List`.\n *\n * @example\n * List.of({ k: 3 }, { k: 1 }, { k: 2 })\n * .sortBy(o => o.k, (a, b) => a < b ? Ordering.LessThan : a > b ? Ordering.GreaterThan : Ordering.Equal);\n * // List [{ k: 1 }, { k: 2 }, { k: 3 }]\n */\n public sortBy<K>(f: (value: A) => K, comparator: (a: K, b: K) => Ordering): List<A> {\n return new List(this._items.slice().sort((a, b) => comparator(f(a), f(b)).value));\n }\n\n /**\n * Removes duplicates, keeping the first occurrence of each value. Equality defaults to\n * `Object.is`.\n *\n * @param {(a: A, b: A) => boolean} [eq=Object.is] Optional equality function.\n * @returns {List<A>} A new `List` with duplicates removed.\n *\n * @example\n * List.of(1, 2, 1, 3, 2).distinct().toArray(); // [1, 2, 3]\n */\n public distinct(eq: (a: A, b: A) => boolean = Object.is): List<A> {\n const out: A[] = [];\n for (const item of this._items) {\n if (!out.some((x) => eq(x, item))) out.push(item);\n }\n return new List(out);\n }\n\n /**\n * Inserts `sep` between adjacent elements. For lists of size 0 or 1, this is a no-op.\n *\n * @param {A} sep The separator to interleave.\n * @returns {List<A>} A new `List` with `sep` between original elements.\n *\n * @example\n * List.of(1, 2, 3).intersperse(0).toArray(); // [1, 0, 2, 0, 3]\n * List.of(1).intersperse(0).toArray(); // [1]\n */\n public intersperse(sep: A): List<A> {\n if (this._items.length <= 1) return new List(this._items.slice());\n const out: A[] = [];\n for (let i = 0; i < this._items.length; i++) {\n if (i > 0) out.push(sep);\n out.push(this._items[i]);\n }\n return new List(out);\n }\n\n /**\n * Joins string representations of the elements using a separator.\n *\n * @param {string} [separator=\"\"] The string to place between elements.\n * @returns {string} The joined string. Empty list yields `\"\"`.\n *\n * @example\n * List.of(1, 2, 3).mkString(\", \"); // \"1, 2, 3\"\n * List.empty<number>().mkString(\", \"); // \"\"\n */\n public mkString(separator: string = \"\"): string {\n return this._items.join(separator);\n }\n\n /**\n * Pairs elements with a {@link NonEmptyList}. Stops at the shorter length; may empty.\n *\n * @template B The element type of the other list.\n * @param {NonEmptyList<B>} other The other list.\n * @returns {List<[A, B]>} A `List` of pairs.\n */\n public zip<B>(other: NonEmptyList<B>): List<[A, B]>;\n /**\n * Pairs elements with another `List`. Stops at the shorter length.\n *\n * @template B The element type of the other list.\n * @param {List<B>} other The other list.\n * @returns {List<[A, B]>} A `List` of pairs.\n *\n * @example\n * List.of(1, 2, 3).zip(List.of(\"a\", \"b\")).toArray();\n * // [[1, \"a\"], [2, \"b\"]]\n */\n public zip<B>(other: List<B>): List<[A, B]>;\n public zip<B>(other: List<B> | NonEmptyList<B>): List<[A, B]> {\n const otherArr = other instanceof NonEmptyList ? other.toArray() : other._items;\n const n = Math.min(this._items.length, otherArr.length);\n const out: [A, B][] = new Array(n);\n for (let i = 0; i < n; i++) out[i] = [this._items[i], otherArr[i]];\n return new List(out);\n }\n\n /**\n * Combines paired elements via `f`. Stops at the shorter list.\n *\n * @template B The element type of the other list.\n * @template C The result element type.\n * @param {List<B>} other The other list.\n * @param {(a: A, b: B) => C} f Combines a pair of elements.\n * @returns {List<C>} A `List` of combined values.\n *\n * @example\n * List.of(1, 2, 3).zipWith(List.of(10, 20, 30), (a, b) => a + b).toArray();\n * // [11, 22, 33]\n */\n public zipWith<B, C>(other: List<B>, f: (a: A, b: B) => C): List<C> {\n const n = Math.min(this._items.length, other._items.length);\n const out: C[] = new Array(n);\n for (let i = 0; i < n; i++) out[i] = f(this._items[i], other._items[i]);\n return new List(out);\n }\n\n /**\n * Pairs each element with its zero-based index.\n *\n * @returns {List<[A, number]>} A `List` of `[element, index]` pairs.\n *\n * @example\n * List.of(\"a\", \"b\", \"c\").zipWithIndex().toArray();\n * // [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n */\n public zipWithIndex(): List<[A, number]> {\n const out: [A, number][] = new Array(this._items.length);\n for (let i = 0; i < this._items.length; i++) out[i] = [this._items[i], i];\n return new List(out);\n }\n\n /**\n * Splits a `List` of pairs into a pair of `List`s.\n *\n * @template B First element type.\n * @template C Second element type.\n * @returns {[List<B>, List<C>]} A tuple of two `List`s with the unpacked components.\n *\n * @example\n * const [as, bs] = List.of<[number, string]>([1, \"a\"], [2, \"b\"]).unzip<number, string>();\n * as.toArray(); // [1, 2]\n * bs.toArray(); // [\"a\", \"b\"]\n */\n public unzip<B, C>(this: List<[B, C]>): [List<B>, List<C>] {\n const bs: B[] = new Array(this._items.length);\n const cs: C[] = new Array(this._items.length);\n for (let i = 0; i < this._items.length; i++) {\n bs[i] = this._items[i][0];\n cs[i] = this._items[i][1];\n }\n return [new List(bs), new List(cs)];\n }\n\n /**\n * Groups elements by a key extracted via `f`. Iteration order in the resulting `Map`\n * reflects the order each key was first encountered. Each group is non-empty by\n * construction.\n *\n * @template K The key type.\n * @param {(value: A) => K} f Extracts the group key.\n * @returns {Map<K, NonEmptyList<A>>} A `Map` of group keys to their members.\n *\n * @example\n * List.of(1, 2, 3, 4, 5).groupBy(n => n % 2);\n * // Map { 1 => NonEmptyList [1, 3, 5], 0 => NonEmptyList [2, 4] }\n */\n public groupBy<K>(f: (value: A) => K): Map<K, NonEmptyList<A>> {\n const buckets = new Map<K, A[]>();\n for (const item of this._items) {\n const k = f(item);\n const existing = buckets.get(k);\n if (existing) existing.push(item);\n else buckets.set(k, [item]);\n }\n const out = new Map<K, NonEmptyList<A>>();\n for (const [k, arr] of buckets) {\n out.set(k, new NonEmptyList(arr[0], new List(arr.slice(1))));\n }\n return out;\n }\n\n /**\n * Splits the list into consecutive chunks of size `n` (the last chunk may be smaller).\n * Each chunk is a {@link NonEmptyList}.\n *\n * @param {number} n The maximum chunk size; must be positive.\n * @returns {List<NonEmptyList<A>>} A `List` of non-empty chunks.\n * @throws {Error} If `n <= 0`.\n *\n * @example\n * List.of(1, 2, 3, 4, 5).chunk(2).toArray().map(c => c.toArray());\n * // [[1, 2], [3, 4], [5]]\n */\n public chunk(n: number): List<NonEmptyList<A>> {\n if (n <= 0) throw new Error(\"List.chunk size must be positive.\");\n const out: NonEmptyList<A>[] = [];\n for (let i = 0; i < this._items.length; i += n) {\n const slice = this._items.slice(i, i + n);\n out.push(new NonEmptyList(slice[0], new List(slice.slice(1))));\n }\n return new List(out);\n }\n\n /**\n * Returns sliding windows of size `n` over the list. If `n > size`, returns the empty list.\n *\n * @param {number} n The window size; must be positive.\n * @returns {List<NonEmptyList<A>>} A `List` of windows.\n * @throws {Error} If `n <= 0`.\n *\n * @example\n * List.of(1, 2, 3, 4).sliding(2).toArray().map(w => w.toArray());\n * // [[1, 2], [2, 3], [3, 4]]\n */\n public sliding(n: number): List<NonEmptyList<A>> {\n if (n <= 0) throw new Error(\"List.sliding size must be positive.\");\n if (n > this._items.length) return List.empty();\n const out: NonEmptyList<A>[] = [];\n for (let i = 0; i + n <= this._items.length; i++) {\n const slice = this._items.slice(i, i + n);\n out.push(new NonEmptyList(slice[0], new List(slice.slice(1))));\n }\n return new List(out);\n }\n\n /**\n * Lifts a function `A => F<B>` over the list, producing `F<List<B>>` — where `F` is one of\n * the library's effect types. The first argument selects the effect; the return type and\n * evaluation strategy follow from it.\n *\n * - `traverse(IO, f)` — sequential, fails fast on the first error (uses `IO`'s flatMap).\n * - `traverse(Either, f)` — short-circuits on the first `Left`.\n * - `traverse(Option, f)` — short-circuits on the first `None`.\n * - `traverse(Promise, f)` — parallel via `Promise.all`. For sequential async use\n * `traverse(IO, n => IO.lift(async () => …))` — IO is the proper sequential type.\n *\n * @example\n * await list.traverse(IO, (n) => IO.lift(() => n * 10)).unsafeRun();\n * list.traverse(Either, (n) => n > 0 ? Right.pure(n) : Left.pure(\"bad\"));\n * list.traverse(Option, (n) => n > 0 ? Some.pure(n) : None.Instance);\n * await list.traverse(Promise, async (n) => n * 2);\n */\n public traverse<E, B>(eff: typeof IO, f: (value: A) => IO<E, B>): IO<E, List<B>>;\n public traverse<L, B>(eff: typeof Either, f: (value: A) => Either<L, B>): Either<L, List<B>>;\n public traverse<B>(eff: typeof Option, f: (value: A) => Option<B>): Option<List<B>>;\n public traverse<B>(eff: PromiseConstructor, f: (value: A) => Promise<B>): Promise<List<B>>;\n public traverse(eff: unknown, f: (value: A) => unknown): unknown {\n if (eff === IO) {\n return IO.traverse(this._items.slice(), f as (a: A) => IO<unknown, unknown>);\n }\n if (eff === Either) {\n const out: unknown[] = [];\n for (const item of this._items) {\n const r = f(item);\n if (r instanceof Left) return r;\n out.push((r as Right<unknown>).value);\n }\n return Right.pure(new List(out));\n }\n if (eff === Option) {\n const out: unknown[] = [];\n for (const item of this._items) {\n const r = f(item);\n if (r instanceof Some) out.push((r as Some<unknown>).value);\n else return None.Instance;\n }\n return Some.pure(new List(out) as NonNullable<List<unknown>>);\n }\n if (eff === Promise) {\n return Promise.all(this._items.map(f as (a: A) => Promise<unknown>)).then((arr) => new List(arr));\n }\n throw new Error(`List.traverse: unknown effect type — expected IO, Either, Option, or Promise, got ${String(eff)}`);\n }\n\n /**\n * Returns a string representation of the `List`.\n *\n * @returns {string} A string showing all elements.\n *\n * @example\n * List.of(1, 2, 3).toString(); // \"[1, 2, 3]\"\n * List.empty<number>().toString(); // \"[]\"\n */\n public toString(): string {\n return `[${this._items.join(\", \")}]`;\n }\n}\n","import { IO } from \"./io\";\n\n/**\n * Represents a scheduling policy with configurable retries, delay factor, initial delay, and optional timeout.\n */\nexport interface Policy {\n /**\n * The maximum number of retry attempts. Must be a positive integer.\n */\n readonly recurs: number;\n\n /**\n * The factor by which the delay increases after each retry. Must be greater than or equal to 1.\n */\n readonly factor: number;\n\n /**\n * The initial delay in milliseconds before the first retry. Must be non-negative.\n */\n readonly delay: number;\n\n /**\n * Optional. The maximum duration in milliseconds that each attempt can take before timing out.\n * If not set, attempts will not time out.\n */\n readonly timeout?: number;\n\n /**\n * Optional. A randomization factor between 0 and 1.\n * If set, adds random jitter to the delay to prevent thundering herd problems.\n * For example, a factor of 0.1 adds up to +/- 10% variation to the delay.\n */\n readonly jitter?: number;\n}\n\n/**\n * Provides a default policy configuration.\n *\n * @param {number} recurs - The maximum number of retries.\n * @param {number} factor - The factor by which the delay increases after each retry.\n * @param {number} delay - The initial delay before the first retry, in milliseconds.\n * @param {number} [timeout] - The optional timeout for each attempt, in milliseconds.\n * @param {number} [jitter] - The randomization factor (0-1). Defaults to 0.\n * @returns {Policy} The default policy.\n */\nexport const defaultPolicy = (\n recurs: number = 3,\n factor: number = 1.2,\n delay: number = 1000,\n timeout?: number,\n jitter: number = 0\n): Policy => {\n return { recurs, factor, delay, timeout, jitter };\n};\n\n/**\n * Creates a delay promise that resolves after `ms` milliseconds, or rejects\n * immediately if the signal is already aborted or fires during the delay.\n */\nconst abortableDelay = <E>(ms: number, signal: AbortSignal, liftE: (error: Error) => E): Promise<void> =>\n new Promise<void>((resolve, reject) => {\n if (signal.aborted) {\n reject(liftE(new CancellationError(\"Operation was cancelled\")));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n function onAbort() {\n clearTimeout(timeoutId);\n reject(liftE(new CancellationError(\"Operation was cancelled\")));\n }\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n/**\n * Represents a scheduling strategy for retrying asynchronous operations.\n *\n * Schedule integrates with IO's cancellation model through `AbortSignal`. When an IO\n * running a scheduled operation is cancelled (via `fiber.cancel()` or `IO.timeout`),\n * the signal propagates into the schedule's delay loops and aborts them immediately.\n *\n * The manual `cancel()` method is still supported for standalone usage outside IO.\n *\n * @template A - The type of the result returned by the asynchronous operations.\n */\nexport class Schedule {\n private readonly policy: Policy;\n private readonly controller: AbortController = new AbortController();\n\n /**\n * Constructs a new Schedule instance.\n *\n * @param {Policy} policy - The scheduling policy to use for retries.\n */\n constructor(policy: Policy = defaultPolicy()) {\n if (policy.recurs !== Infinity && (!Number.isFinite(policy.recurs) || policy.recurs < 1)) {\n throw new PolicyValidationError(\"Policy validation error: 'recurs' must be a positive number >= 1 (or Infinity)\");\n }\n if (!Number.isFinite(policy.factor) || policy.factor < 1) {\n throw new PolicyValidationError(\"Policy validation error: 'factor' must be a finite number >= 1\");\n }\n if (!Number.isFinite(policy.delay) || policy.delay < 0) {\n throw new PolicyValidationError(\"Policy validation error: 'delay' must be a finite non-negative number\");\n }\n if (policy.timeout !== undefined && (!Number.isFinite(policy.timeout) || policy.timeout < 0)) {\n throw new PolicyValidationError(\"Policy validation error: 'timeout' must be a finite non-negative number\");\n }\n if (policy.jitter !== undefined && (!Number.isFinite(policy.jitter) || policy.jitter < 0 || policy.jitter > 1)) {\n throw new PolicyValidationError(\"Policy validation error: 'jitter' must be a finite number between 0 and 1\");\n }\n this.policy = policy;\n }\n\n /**\n * Wraps an IO operation with retry logic based on a defined policy and a specific condition.\n * The operation is retried with an increasing delay, which grows according to the policy factor.\n * If an operation exceeds the retry limit or fails due to other reasons, a RetryError is thrown.\n *\n * Cancellation is supported through two mechanisms:\n * - **IO signal**: When the IO running this schedule is cancelled (fiber, timeout), the AbortSignal\n * propagates and aborts any in-progress delay immediately.\n * - **Manual cancel()**: Calling `schedule.cancel()` aborts the internal controller, which has the\n * same effect.\n *\n * @template E The error type inside the IO.\n * @template A The potential result of the IO operation.\n *\n * @param {IO<E, A>} eff The operation to retry.\n * @param {(error: E) => boolean} condition The condition under which to retry the operation.\n * @param {(error: Error) => E} liftE A function that transforms a generic Error into an instance of E.\n *\n * @returns {IO<E, A>} An IO instance that encapsulates the original operation's result if successful,\n * or encapsulates a RetryError if the retry limit is reached without success.\n */\n retryIf<E, A>(eff: IO<E, A>, condition: (error: E) => boolean, liftE: (error: Error) => E): IO<E, A> {\n const policy = this.policy;\n const manualSignal = this.controller.signal;\n\n return IO.cancellable<E, A>(\n async (ioSignal: AbortSignal) => {\n // Merge IO signal and manual cancel signal: abort when either fires\n const merged = new AbortController();\n const abortMerged = () => merged.abort();\n\n if (ioSignal.aborted || manualSignal.aborted) {\n throw liftE(new CancellationError(\"Operation was cancelled\"));\n }\n\n ioSignal.addEventListener(\"abort\", abortMerged, { once: true });\n manualSignal.addEventListener(\"abort\", abortMerged, { once: true });\n\n try {\n let attempt = 0;\n let delay = policy.delay;\n\n while (attempt < policy.recurs) {\n if (merged.signal.aborted) {\n throw liftE(new CancellationError(\"Operation was cancelled\"));\n }\n\n const result = await this.withTimeout(eff, liftE).unsafeRun();\n if (result.type === \"Ok\") {\n return result.value;\n }\n const error = result.error;\n\n let shouldRetry: boolean;\n try {\n shouldRetry = condition(error);\n } catch (conditionError) {\n throw liftE(\n new ConditionalRetryError(\n `Retry condition threw: ${conditionError instanceof Error ? conditionError.message : String(conditionError)}`\n )\n );\n }\n\n if (!shouldRetry) {\n throw liftE(new ConditionalRetryError(`Retry condition not met: ${error}`));\n }\n if (attempt >= policy.recurs - 1) {\n throw liftE(new RetryError(`Retry limit reached without success: ${error}`));\n }\n\n await abortableDelay(this.applyJitter(delay), merged.signal, liftE);\n\n delay *= policy.factor;\n attempt++;\n }\n throw liftE(new RetryError(\"Retry limit reached without success\"));\n } finally {\n ioSignal.removeEventListener(\"abort\", abortMerged);\n manualSignal.removeEventListener(\"abort\", abortMerged);\n }\n },\n (e: unknown) => (isLiftedError<E>(e) ? e : liftE(e instanceof Error ? e : new Error(String(e))))\n );\n }\n\n /**\n * Repeats the execution of an IO action based on a defined scheduling policy.\n * If the IO action succeeds, it is executed again until it either fails or the policy determines the execution should stop.\n *\n * Cancellation is supported through both the IO signal and `schedule.cancel()`.\n *\n * @template E The error type inside the IO.\n * @template A The potential result of the IO action.\n *\n * @param {IO<E, A>} eff The IO action to repeat.\n * @param {(error: Error) => E} liftE A function that transforms a generic Error into an instance of E.\n *\n * @returns {IO<E, A>} An IO instance that encapsulates the last successful result\n * or a RepeatError if the action fails or exhausts the retries determined by the policy.\n */\n repeat<E, A>(eff: IO<E, A>, liftE: (error: Error) => E): IO<E, A> {\n const policy = this.policy;\n const manualSignal = this.controller.signal;\n\n return IO.cancellable<E, A>(\n async (ioSignal: AbortSignal) => {\n const merged = new AbortController();\n const abortMerged = () => merged.abort();\n\n if (ioSignal.aborted || manualSignal.aborted) {\n throw liftE(new CancellationError(\"Operation was cancelled\"));\n }\n\n ioSignal.addEventListener(\"abort\", abortMerged, { once: true });\n manualSignal.addEventListener(\"abort\", abortMerged, { once: true });\n\n try {\n let hasResult = false;\n let lastSuccessResult: A | undefined;\n let delay = policy.delay;\n\n for (let attempt = 0; attempt < policy.recurs; attempt++) {\n if (merged.signal.aborted) {\n throw liftE(new CancellationError(\"Operation was cancelled\"));\n }\n\n const result = await this.withTimeout(eff, liftE).unsafeRun();\n\n if (result.type === \"Ok\") {\n hasResult = true;\n lastSuccessResult = result.value;\n\n if (attempt < policy.recurs - 1) {\n await abortableDelay(this.applyJitter(delay), merged.signal, liftE);\n delay *= policy.factor;\n }\n } else {\n throw liftE(new RepeatError(`Failed to execute repeat: ${result.error}`));\n }\n }\n\n if (hasResult) {\n return lastSuccessResult as A;\n }\n\n throw liftE(new RepeatError(\"The function provided never succeeded\"));\n } finally {\n ioSignal.removeEventListener(\"abort\", abortMerged);\n manualSignal.removeEventListener(\"abort\", abortMerged);\n }\n },\n (e: unknown) => (isLiftedError<E>(e) ? e : liftE(e instanceof Error ? e : new Error(String(e))))\n );\n }\n\n /**\n * Wraps an IO operation with an optional timeout configured by the scheduler policy.\n * If a valid timeout is provided and the operation exceeds this time,\n * it encapsulates a TimeoutError within the IO instance.\n *\n * @template E The error type inside the IO.\n * @template A The potential result of the IO operation.\n *\n * @param {IO<E, A>} eff The operation to wrap with the policy timeout.\n * @param {(error: Error) => E} liftE A function that transforms a generic Error into an instance of E.\n *\n * @returns {IO<E, A>} An IO instance that either encapsulates the original operation's result\n * or a TimeoutError if the timeout is exceeded.\n */\n withTimeout<E, A>(eff: IO<E, A>, liftE: (error: Error) => E): IO<E, A> {\n const timeout = this.policy.timeout;\n if (!timeout || timeout < 1) {\n return eff;\n }\n\n return IO.lift<E, A>(async () => {\n let timeoutId: NodeJS.Timeout | null = null;\n let settled = false;\n\n const timeoutP = new Promise<A>((_, reject) => {\n timeoutId = setTimeout(() => {\n if (settled) return;\n settled = true;\n reject(liftE(new TimeoutError(`The operation timed out after ${timeout} milliseconds`)));\n }, timeout);\n });\n\n const opP = eff.unsafeRun().then((result) => {\n if (settled) return result.type === \"Ok\" ? result.value : Promise.reject(result.error);\n settled = true;\n if (timeoutId) clearTimeout(timeoutId);\n switch (result.type) {\n case \"Ok\":\n return result.value;\n case \"Err\":\n return Promise.reject(result.error);\n }\n });\n\n try {\n return await Promise.race([opP, timeoutP]);\n } catch (error) {\n if (timeoutId) clearTimeout(timeoutId);\n return Promise.reject(error);\n }\n });\n }\n\n /**\n * Cancels the ongoing scheduled operation. Aborts any in-progress delay immediately.\n *\n * This works both when the schedule is used standalone and when it's running inside an IO.\n * For IO-managed schedules (via `retryIf` on IO), cancellation through `fiber.cancel()` or\n * `IO.timeout` is preferred — it automatically propagates through the AbortSignal.\n *\n * @example\n * const schedule = new Schedule();\n * const operation = schedule.retryIf(eff, () => true, e => e);\n *\n * setTimeout(() => schedule.cancel(), 150);\n * const result = await operation.unsafeRun();\n */\n cancel(): void {\n this.controller.abort();\n }\n\n private applyJitter(delay: number): number {\n if (!this.policy.jitter) return delay;\n const amount = delay * this.policy.jitter;\n const offset = (Math.random() * 2 - 1) * amount;\n return Math.max(0, delay + offset);\n }\n}\n\n/**\n * Type guard: returns true if the value was already lifted through `liftE` and should not be double-wrapped.\n * We detect this by checking if the value is NOT a plain Error subclass from this module.\n */\nconst isLiftedError = <E>(e: unknown): e is E =>\n !(\n e instanceof CancellationError ||\n e instanceof RetryError ||\n e instanceof RepeatError ||\n e instanceof ConditionalRetryError ||\n e instanceof TimeoutError ||\n e instanceof PolicyValidationError\n );\n\n/**\n * Represents an error related to invalid scheduling policy configurations.\n * @extends Error\n */\nexport class PolicyValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PolicyValidationError\";\n }\n}\n\n/**\n * Represents an error that occurs when an operation exceeds the allowed timeout limit.\n * @extends Error\n */\nexport class TimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TimeoutError\";\n }\n}\n\n/**\n * Represents an error that occurs when a retry condition is not met or the condition function itself throws.\n * @extends Error\n */\nexport class ConditionalRetryError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConditionalRetryError\";\n }\n}\n\n/**\n * Represents an error that occurs when the maximum number of retries is reached.\n * @extends Error\n */\nexport class RetryError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RetryError\";\n }\n}\n\n/**\n * Represents an error that occurs during the repetition of an operation.\n * @extends Error\n */\nexport class RepeatError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RepeatError\";\n }\n}\n\n/**\n * Represents an error that occurs when an operation is cancelled.\n * @extends Error\n */\nexport class CancellationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CancellationError\";\n }\n}\n","import { Either, Left, Right } from \"./either\";\nimport { List } from \"./list\";\nimport { NonEmptyList } from \"./non-empty-list\";\n// Circular dependency: schedule.ts imports IO from this module.\n// Safe because both modules only reference each other's exports at runtime (inside methods),\n// never at import/evaluation time. Do not add top-level code that uses Schedule eagerly.\nimport { defaultPolicy, Policy, Schedule } from \"./schedule\";\n\nexport interface Ok<A> {\n type: \"Ok\";\n value: A;\n}\n\nexport interface Err<E> {\n type: \"Err\";\n error: E;\n}\n\nexport interface Cancelled {\n type: \"Cancelled\";\n}\n\nexport interface Fiber<E, A> {\n /** Wait for the computation to complete. */\n readonly join: () => Promise<Ok<A> | Err<E> | Cancelled>;\n /** Request cancellation. Idempotent. Resolves after finalizers run. */\n readonly cancel: () => Promise<void>;\n /** The underlying AbortSignal for interop with platform APIs. */\n readonly signal: AbortSignal;\n}\n\ntype Node<E, A> =\n | { tag: \"Pure\"; value: A }\n | { tag: \"Fail\"; error: E }\n | { tag: \"Lift\"; run: (signal?: AbortSignal) => A | Promise<A>; liftE?: (e: unknown) => E }\n | { tag: \"Map\"; io: Node<any, any>; f: (a: any) => A }\n | { tag: \"FlatMap\"; io: Node<any, any>; f: (a: any) => IO<any, A> }\n | { tag: \"MapErr\"; io: Node<any, any>; f: (e: any) => E }\n | { tag: \"FlatMapErr\"; io: Node<any, any>; f: (e: any) => IO<E, A> }\n | { tag: \"Tap\"; io: Node<E, A>; f: (a: any) => void | Promise<void> }\n | { tag: \"TapErr\"; io: Node<E, A>; f: (e: any) => void | Promise<void> }\n | { tag: \"Ensure\"; io: Node<E, A>; predicate: (a: any) => boolean; liftE: (a: any) => E }\n | { tag: \"FoldM\"; io: Node<any, any>; onOk: (a: any) => IO<E, A>; onErr: (e: any) => IO<E, A> }\n | { tag: \"OnCancel\"; io: Node<E, A>; finalizer: () => void | Promise<void> };\n\ntype Frame =\n | { tag: \"Map\"; f: (a: any) => any }\n | { tag: \"FlatMap\"; f: (a: any) => IO<any, any> }\n | { tag: \"MapErr\"; f: (e: any) => any }\n | { tag: \"FlatMapErr\"; f: (e: any) => IO<any, any> }\n | { tag: \"Tap\"; f: (a: any) => void | Promise<void> }\n | { tag: \"TapErr\"; f: (e: any) => void | Promise<void> }\n | { tag: \"FoldM\"; onOk: (a: any) => IO<any, any>; onErr: (e: any) => IO<any, any> }\n | { tag: \"Ensure\"; predicate: (a: any) => boolean; liftE: (a: any) => any }\n | { tag: \"OnCancel\"; finalizer: () => void | Promise<void> };\n\n/** Module-private key for IO's ADT node. Not exported — external code cannot access it. */\nconst NODE = Symbol(\"IO.node\");\n\n/** Module-private sentinel tag for typed error escape in Do/parMapN/race. */\nconst IO_ESCAPE = Symbol(\"IO.escape\");\n\ninterface IOEscape<E> {\n readonly [IO_ESCAPE]: true;\n readonly error: E;\n}\n\nfunction ioEscape<E>(error: E): IOEscape<E> {\n return { [IO_ESCAPE]: true, error };\n}\n\nfunction isIOEscape(e: unknown): e is IOEscape<any> {\n return e != null && typeof e === \"object\" && IO_ESCAPE in (e as object);\n}\n\n/** Module-private sentinel for cancellation propagation through Lift boundaries. */\nconst IO_CANCELLED = Symbol(\"IO.cancelled\");\n\ninterface IOCancelled {\n readonly [IO_CANCELLED]: true;\n}\n\nfunction ioCancelled(): never {\n throw { [IO_CANCELLED]: true } as IOCancelled;\n}\n\nfunction isIOCancelled(e: unknown): e is IOCancelled {\n return e != null && typeof e === \"object\" && IO_CANCELLED in (e as object);\n}\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return value != null && typeof (value as any).then === \"function\";\n}\n\nasync function interpret<E, A>(root: Node<E, A>, signal?: AbortSignal): Promise<Ok<A> | Err<E> | Cancelled> {\n const stack: Frame[] = [];\n let cur: Node<any, any> = root;\n\n while (true) {\n if (signal?.aborted) {\n const finalizers: Array<() => void | Promise<void>> = [];\n while (stack.length > 0) {\n const frame = stack.pop()!;\n if (frame.tag === \"OnCancel\") {\n finalizers.push(frame.finalizer);\n }\n }\n for (const fin of finalizers) {\n try {\n const r = fin();\n if (isThenable(r)) await r;\n } catch {\n /* swallow */\n }\n }\n return { type: \"Cancelled\" };\n }\n\n switch (cur.tag) {\n case \"Map\":\n stack.push({ tag: \"Map\", f: cur.f });\n cur = cur.io;\n break;\n case \"FlatMap\":\n stack.push({ tag: \"FlatMap\", f: cur.f });\n cur = cur.io;\n break;\n case \"MapErr\":\n stack.push({ tag: \"MapErr\", f: cur.f });\n cur = cur.io;\n break;\n case \"FlatMapErr\":\n stack.push({ tag: \"FlatMapErr\", f: cur.f });\n cur = cur.io;\n break;\n case \"Tap\":\n stack.push({ tag: \"Tap\", f: cur.f });\n cur = cur.io;\n break;\n case \"TapErr\":\n stack.push({ tag: \"TapErr\", f: cur.f });\n cur = cur.io;\n break;\n case \"FoldM\":\n stack.push({ tag: \"FoldM\", onOk: cur.onOk, onErr: cur.onErr });\n cur = cur.io;\n break;\n case \"Ensure\":\n stack.push({ tag: \"Ensure\", predicate: cur.predicate, liftE: cur.liftE });\n cur = cur.io;\n break;\n case \"OnCancel\":\n stack.push({ tag: \"OnCancel\", finalizer: cur.finalizer });\n cur = cur.io;\n break;\n\n case \"Lift\": {\n const { run, liftE } = cur;\n try {\n const result = run(signal);\n const value = isThenable(result) ? await result : result;\n cur = { tag: \"Pure\", value };\n } catch (e) {\n if (isIOCancelled(e)) {\n // Child computation was cancelled — propagate by letting the\n // cancellation check at the top of the loop fire\n cur = { tag: \"Pure\", value: undefined }; // dummy, will be overridden\n break;\n }\n cur = { tag: \"Fail\", error: liftE ? liftE(e) : e };\n }\n break;\n }\n\n case \"Pure\": {\n if (stack.length === 0) return { type: \"Ok\", value: cur.value };\n\n const frame = stack.pop()!;\n switch (frame.tag) {\n case \"Map\":\n try {\n cur = { tag: \"Pure\", value: frame.f(cur.value) };\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n case \"FlatMap\":\n try {\n cur = frame.f(cur.value)[NODE];\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n case \"Tap\":\n try {\n const r = frame.f(cur.value);\n if (isThenable(r)) await r;\n } catch {\n // Side-effect failure is swallowed — tap preserves the original value\n }\n break;\n case \"Ensure\": {\n const val = cur.value;\n try {\n if (!frame.predicate(val)) {\n cur = { tag: \"Fail\", error: frame.liftE(val) };\n }\n } catch {\n // Predicate threw — treat as predicate failure to preserve typed error\n cur = { tag: \"Fail\", error: frame.liftE(val) };\n }\n break;\n }\n case \"FoldM\":\n try {\n cur = frame.onOk(cur.value)[NODE];\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n // Error-only frames: pass through on Ok\n case \"MapErr\":\n case \"FlatMapErr\":\n case \"TapErr\":\n case \"OnCancel\":\n break;\n }\n break;\n }\n\n case \"Fail\": {\n if (stack.length === 0) return { type: \"Err\", error: cur.error };\n\n const frame = stack.pop()!;\n switch (frame.tag) {\n case \"MapErr\":\n try {\n cur = { tag: \"Fail\", error: frame.f(cur.error) };\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n case \"FlatMapErr\":\n try {\n cur = frame.f(cur.error)[NODE];\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n case \"TapErr\":\n try {\n const r = frame.f(cur.error);\n if (isThenable(r)) await r;\n } catch {\n // Side-effect failure is swallowed — tapErr preserves the original error\n }\n break;\n case \"FoldM\":\n try {\n cur = frame.onErr(cur.error)[NODE];\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n // Ok-only frames: pass through on Err\n case \"Map\":\n case \"FlatMap\":\n case \"Tap\":\n case \"Ensure\":\n case \"OnCancel\":\n break;\n }\n break;\n }\n }\n }\n}\n\n/**\n * `IO<E, A>` represents a lazy, composable description of an effectful computation\n * that may succeed with a value of type `A` or fail with an error of type `E`.\n *\n * Computations are described as an immutable ADT tree and only executed when\n * `unsafeRun()` is called. The interpreter uses an explicit stack (trampoline)\n * to evaluate the tree, ensuring stack safety for arbitrarily deep chains.\n */\nexport class IO<E, A> {\n /** @internal Keyed by module-private Symbol — inaccessible to external code. */\n readonly [NODE]: Node<E, A>;\n\n /** @internal */\n private constructor(node: Node<E, A>) {\n this[NODE] = node;\n }\n\n /**\n * @internal Type-erased constructor for combinators that change E or A.\n * Use `new IO(...)` when the return type matches `IO<E, A>` (same types).\n * Use `IO.wrap(...)` when the combinator changes E or A (e.g. map, flatMap, mapErr, foldM).\n */\n private static wrap<E, A>(node: Node<any, any>): IO<E, A> {\n return new IO<E, A>(node as Node<E, A>);\n }\n\n /**\n * Creates an IO from an effectful function that may be synchronous or asynchronous.\n * The function is not executed until `unsafeRun()` is called on the resulting IO,\n * preserving laziness. The interpreter detects whether the return value is a\n * Promise at runtime and awaits only when necessary.\n *\n * If the function throws (or the returned Promise rejects), the error is captured\n * as the `Err` channel. When `liftE` is provided, caught exceptions are transformed\n * into the error type `E` before being placed in the error channel.\n *\n * @template E The error type.\n * @template A The success type.\n * @param {() => A | Promise<A>} f The effectful function to defer.\n * @param {(e: unknown) => E} [liftE] Optional function to transform caught exceptions into the error type E.\n * @returns {IO<E, A>} A new IO that, when executed, will run the function and capture its result.\n *\n * @example\n * // Synchronous effect\n * const syncIO = IO.lift(() => 42);\n *\n * // Asynchronous effect\n * const asyncIO = IO.lift(() => fetch('/api/data').then(r => r.json()));\n *\n * // With error transformation\n * const typedIO = IO.lift(\n * () => riskyOperation(),\n * (e) => new AppError(String(e))\n * );\n */\n static lift<E, A>(f: (signal?: AbortSignal) => A | Promise<A>, liftE?: (e: unknown) => E): IO<E, A> {\n return new IO({ tag: \"Lift\", run: f, liftE });\n }\n\n /**\n * Creates an IO from a function that receives an `AbortSignal` for cooperative cancellation.\n * Use this when the underlying operation supports cancellation (e.g., `fetch`, streams, timers).\n *\n * The signal is provided by the interpreter when the IO is forked. If the IO is run\n * without forking (via `unsafeRun`), the signal is never aborted.\n *\n * @template E The error type.\n * @template A The success type.\n * @param {(signal: AbortSignal) => A | Promise<A>} f The cancellable effectful function.\n * @param {(e: unknown) => E} [liftE] Optional function to transform caught exceptions into E.\n * @returns {IO<E, A>} A new IO that cooperates with cancellation.\n *\n * @example\n * const io = IO.cancellable<AppError, Response>(\n * (signal) => fetch('/api/data', { signal }),\n * (e) => new AppError(String(e))\n * );\n */\n static cancellable<E, A>(f: (signal: AbortSignal) => A | Promise<A>, liftE?: (e: unknown) => E): IO<E, A> {\n return new IO({ tag: \"Lift\", run: (signal?: AbortSignal) => f(signal ?? new AbortController().signal), liftE });\n }\n\n /**\n * Guarantees resource cleanup by structuring effectful code into three phases:\n * **acquire**, **use**, and **release**. The release action is *always* executed,\n * regardless of whether `use` succeeds, fails, or is cancelled.\n *\n * This is the classic functional `bracket` pattern (Cats `bracket`, Haskell `bracket`,\n * ZIO `acquireRelease`). It eliminates resource leaks by construction — the type\n * system ensures that every acquired resource has a corresponding release.\n *\n * Semantics:\n * - If **acquire** fails or is cancelled, `use` and `release` are never called.\n * - If **use** succeeds, `release` runs and the success value is returned.\n * - If **use** fails, `release` runs and the original error is returned.\n * - If **use** is cancelled, `release` runs and `Cancelled` is propagated.\n * - **release** runs without an `AbortSignal` — it always runs to completion.\n * - If `release` itself fails, the error is swallowed and `use`'s result takes priority\n * (following Cats Effect semantics).\n *\n * @template E The error type shared by acquire and use.\n * @template R The resource type produced by acquire.\n * @template A The success type produced by use.\n * @param {IO<E, R>} acquire An IO that acquires the resource.\n * @param {(r: R) => IO<E, A>} use A function that uses the resource and produces a result.\n * @param {(r: R) => IO<never, void>} release A function that releases the resource. Must not fail.\n * @returns {IO<E, A>} An IO that acquires, uses, and releases the resource.\n *\n * @example\n * // Database connection with guaranteed cleanup\n * const io = IO.bracket(\n * IO.lift(() => openConnection()),\n * (conn) => IO.lift(() => conn.query('SELECT * FROM users')),\n * (conn) => IO.lift(() => conn.close())\n * );\n *\n * @example\n * // File handle with guaranteed close\n * const io = IO.bracket(\n * IO.lift(() => fs.open('/tmp/data.txt', 'r')),\n * (fd) => IO.lift(() => fs.read(fd, buffer, 0, 1024, 0)),\n * (fd) => IO.lift(() => fs.close(fd))\n * );\n *\n * @example\n * // Composable with other IO combinators\n * const io = IO.bracket(\n * acquirePool(),\n * (pool) => queryUsers(pool).map(users => users.filter(u => u.active)),\n * (pool) => IO.lift(() => pool.shutdown())\n * ).mapErr(e => new AppError(e));\n */\n static bracket<E, R, A>(acquire: IO<E, R>, use: (r: R) => IO<E, A>, release: (r: R) => IO<never, void>): IO<E, A> {\n return IO.lift<E, A>(\n async (signal?: AbortSignal) => {\n // Phase 1: Acquire — respects cancellation\n const acqResult = await interpret(acquire[NODE], signal);\n if (acqResult.type === \"Cancelled\") ioCancelled();\n if (acqResult.type === \"Err\") throw ioEscape(acqResult.error);\n\n const resource = acqResult.value;\n\n // Phase 2: Use — respects cancellation, but release is guaranteed after\n let useResult: Ok<A> | Err<E> | Cancelled;\n try {\n useResult = await interpret(use(resource)[NODE], signal);\n } catch (e) {\n // use() threw during IO construction — still release\n await interpret(release(resource)[NODE]).catch(() => {});\n throw e;\n }\n\n // Phase 3: Release — always runs, no signal (must complete), errors swallowed\n await interpret(release(resource)[NODE]).catch(() => {});\n\n // Propagate use's original outcome\n if (useResult.type === \"Cancelled\") ioCancelled();\n if (useResult.type === \"Err\") throw ioEscape(useResult.error);\n return useResult.value;\n },\n (e: unknown) => {\n if (isIOCancelled(e)) throw e;\n if (isIOEscape(e)) return e.error as E;\n return e as E;\n }\n );\n }\n\n /**\n * Lifts an already-computed value into IO with no side effect.\n * The value is available immediately — no deferred computation takes place.\n *\n * This is useful for wrapping a known value in the IO type so it can be composed\n * with other IO operations via `flatMap`, `map`, etc.\n *\n * @template A The type of the value.\n * @param {A} a The value to wrap.\n * @returns {IO<never, A>} An IO that immediately succeeds with the given value.\n *\n * @example\n * const io = IO.pure(42);\n * const result = await io.unsafeRun(); // { type: \"Ok\", value: 42 }\n */\n static pure<A>(a: A): IO<never, A> {\n return new IO({ tag: \"Pure\", value: a });\n }\n\n /**\n * Creates an IO that fails immediately with the given error.\n * No computation is performed — the error is placed directly in the error channel.\n *\n * @template E The error type.\n * @template A The success type (defaults to `never` since this IO never succeeds).\n * @param {E} error The error value.\n * @returns {IO<E, A>} An IO that immediately fails with the given error.\n *\n * @example\n * const io = IO.fail(new Error(\"something went wrong\"));\n * const result = await io.unsafeRun(); // { type: \"Err\", error: Error(\"something went wrong\") }\n */\n static fail<E, A = never>(error: E): IO<E, A> {\n return new IO({ tag: \"Fail\", error });\n }\n\n /**\n * An IO that succeeds with `void`. Useful as a no-op placeholder\n * or as the terminal value in a chain of side-effecting operations.\n *\n * @example\n * const io = IO.unit;\n * const result = await io.unsafeRun(); // { type: \"Ok\", value: undefined }\n */\n static readonly unit: IO<never, void> = new IO<never, void>({\n tag: \"Pure\",\n value: undefined as unknown as void,\n });\n\n /**\n * Creates an Ok result value. Convenience constructor for building result values\n * outside of the IO execution context.\n *\n * @template A The type of the success value.\n * @param {A} value The success value.\n * @returns {Ok<A>} A result representing success.\n */\n static ok<A>(value: A): Ok<A> {\n return { type: \"Ok\", value };\n }\n\n /**\n * Creates an Err result value. Convenience constructor for building result values\n * outside of the IO execution context.\n *\n * @template E The type of the error value.\n * @param {E} error The error value.\n * @returns {Err<E>} A result representing failure.\n */\n static err<E>(error: E): Err<E> {\n return { type: \"Err\", error };\n }\n\n /**\n * Transforms the success value of this IO using the provided function.\n * If this IO fails, the function is not called and the error propagates unchanged.\n *\n * This is an O(1) operation — it wraps the current computation in a new node\n * without executing anything.\n *\n * @template B The type of the transformed value.\n * @param {(a: A) => B} f The transformation function.\n * @returns {IO<E, B>} A new IO representing the transformed computation.\n *\n * @example\n * const io = IO.lift(() => 21).map(n => n * 2);\n * const result = await io.unsafeRun(); // { type: \"Ok\", value: 42 }\n */\n map<B>(f: (a: A) => B): IO<E, B> {\n return IO.wrap({ tag: \"Map\", io: this[NODE], f });\n }\n\n /**\n * Chains a dependent IO computation on the success value.\n * If this IO fails, the function is not called and the error propagates unchanged.\n *\n * This is the monadic `bind` operation, enabling sequential composition of IO\n * operations where each step may depend on the result of the previous one.\n *\n * @template B The type of the value produced by the chained computation.\n * @param {(a: A) => IO<E, B>} f A function that takes the success value and returns a new IO.\n * @returns {IO<E, B>} A new IO representing the composed computation.\n *\n * @example\n * const io = IO.lift(() => 1).flatMap(n => IO.lift(() => n + 1));\n * const result = await io.unsafeRun(); // { type: \"Ok\", value: 2 }\n */\n flatMap<B>(f: (a: A) => IO<E, B>): IO<E, B> {\n return IO.wrap({ tag: \"FlatMap\", io: this[NODE], f });\n }\n\n /**\n * Transforms the error value of this IO using the provided function.\n * If this IO succeeds, the function is not called and the value propagates unchanged.\n *\n * Useful for converting raw exceptions or generic errors into typed domain errors.\n *\n * @template F The type of the transformed error.\n * @param {(e: E) => F} f The error transformation function.\n * @returns {IO<F, A>} A new IO with the transformed error type.\n *\n * @example\n * const io = IO.lift(() => { throw new Error(\"boom\"); })\n * .mapErr(e => new AppError(e.message));\n */\n mapErr<F>(f: (e: E) => F): IO<F, A> {\n return IO.wrap({ tag: \"MapErr\", io: this[NODE], f });\n }\n\n /**\n * Transforms both the error and success channels simultaneously.\n * This is the Bifunctor `bimap` operation.\n *\n * @template F The transformed error type.\n * @template B The transformed success type.\n * @param {(e: E) => F} fe The error transformation function.\n * @param {(a: A) => B} fa The success transformation function.\n * @returns {IO<F, B>} A new IO with both channels transformed.\n *\n * @example\n * const io = IO.lift(() => 42)\n * .bimap(\n * err => `Error: ${err}`,\n * val => val * 2\n * );\n */\n bimap<F, B>(fe: (e: E) => F, fa: (a: A) => B): IO<F, B> {\n return this.map(fa).mapErr(fe);\n }\n\n /**\n * Chains a dependent IO computation on the error value.\n * If this IO succeeds, the function is not called and the value propagates unchanged.\n * If this IO fails, the function receives the error and returns a new IO\n * that replaces the failed computation.\n *\n * This is the error-channel counterpart to `flatMap`.\n *\n * @param {(error: E) => IO<E, A>} f A function that takes the error and returns a new IO.\n * @returns {IO<E, A>} A new IO that either succeeds normally or recovers from the error.\n *\n * @example\n * const io = IO.fail(\"not found\")\n * .flatMapErr(err => IO.lift(() => fetchFromFallback()));\n */\n flatMapErr(f: (error: E) => IO<E, A>): IO<E, A> {\n return IO.wrap({ tag: \"FlatMapErr\", io: this[NODE], f });\n }\n\n /**\n * Executes a side-effect on the success value without changing the result.\n * If this IO fails, the function is not called. The callback may be synchronous\n * or asynchronous — the interpreter awaits if it returns a Promise.\n *\n * If the side-effect throws, the exception is swallowed and the original success\n * value is preserved. Use `map` or `flatMap` if failure should propagate.\n *\n * @param {(a: A) => void | Promise<void>} f The side-effect function.\n * @returns {IO<E, A>} A new IO that performs the side-effect but preserves the original result.\n *\n * @example\n * const io = IO.lift(() => 42).tap(value => console.log(\"Got:\", value));\n */\n tap(f: (a: A) => void | Promise<void>): IO<E, A> {\n return IO.wrap({ tag: \"Tap\", io: this[NODE], f });\n }\n\n /**\n * Executes a side-effect on the error value without changing the result.\n * If this IO succeeds, the function is not called. The callback may be synchronous\n * or asynchronous — the interpreter awaits if it returns a Promise.\n *\n * If the side-effect throws, the exception is swallowed and the original error\n * is preserved. Use `mapErr` or `flatMapErr` if failure should propagate.\n *\n * @param {(e: E) => void | Promise<void>} f The side-effect function.\n * @returns {IO<E, A>} A new IO that performs the side-effect but preserves the original error.\n *\n * @example\n * const io = IO.fail(new Error(\"boom\")).tapErr(e => logger.error(e));\n */\n tapErr(f: (e: E) => void | Promise<void>): IO<E, A> {\n return IO.wrap({ tag: \"TapErr\", io: this[NODE], f });\n }\n\n /**\n * Validates the success value against a predicate (Cats `ensure`).\n * If the predicate returns `false`, the success is converted into an error\n * using the `liftE` function. If this IO already fails, the predicate is not checked.\n *\n * @param {(a: A) => boolean} predicate The validation function.\n * @param {(a: A) => E} liftE Converts the value into an error when the predicate fails.\n * @returns {IO<E, A>} A new IO that validates the result.\n *\n * @example\n * const io = IO.lift(() => fetchAge())\n * .ensure(age => age >= 18, age => `Must be 18+, got ${age}`);\n */\n ensure(predicate: (a: A) => boolean, liftE: (a: A) => E): IO<E, A> {\n return IO.wrap({ tag: \"Ensure\", io: this[NODE], predicate, liftE });\n }\n\n /**\n * Registers a cleanup action that runs only if this IO is cancelled.\n * If the IO completes normally (Ok or Err), the finalizer is never called.\n * Finalizers run in LIFO order (innermost first) during cancellation unwinding.\n *\n * @param {() => void | Promise<void>} finalizer The cleanup function.\n * @returns {IO<E, A>} A new IO with the finalizer registered.\n *\n * @example\n * const io = IO.cancellable((signal) => fetch('/api', { signal }))\n * .onCancel(() => console.log(\"Request was cancelled\"));\n */\n onCancel(finalizer: () => void | Promise<void>): IO<E, A> {\n return IO.wrap({ tag: \"OnCancel\", io: this[NODE], finalizer });\n }\n\n /**\n * Monadic fold — branches on both success and error channels, where each arm\n * returns a new IO. Unlike `fold` (which is terminal and returns a plain value),\n * `foldM` produces a composable IO that can be further chained.\n *\n * @template F The error type of the resulting IO.\n * @template B The success type of the resulting IO.\n * @param {(e: E) => IO<F, B>} onErr Handler for the error case.\n * @param {(a: A) => IO<F, B>} onOk Handler for the success case.\n * @returns {IO<F, B>} A new IO representing the branched computation.\n *\n * @example\n * const io = IO.lift(() => riskyOp()).foldM(\n * err => IO.fail(`Recovered: ${err}`),\n * val => IO.pure(val * 2)\n * );\n */\n foldM<F, B>(onErr: (e: E) => IO<F, B>, onOk: (a: A) => IO<F, B>): IO<F, B> {\n return IO.wrap({ tag: \"FoldM\", io: this[NODE], onOk, onErr });\n }\n\n /**\n * Reifies the error channel into the success channel. After `attempt`, the\n * resulting IO cannot fail — its value describes either success or failure\n * as an `Either`. Equivalent to Cats' `attempt` / ZIO's `either`.\n *\n * Unlike `flatMapErr`, which recovers with a replacement IO, `attempt` makes\n * both outcomes observable as values, allowing callers to inspect the error\n * while staying in a non-failing IO.\n *\n * @returns {IO<never, Either<E, A>>} A non-failing IO whose value is `Left(e)` on failure or `Right(a)` on success.\n *\n * @example\n * const io: IO<ApiError, User> = UserService.get(id);\n * const safe = await io.attempt().unsafeRun();\n * // safe: { type: \"Ok\", value: Left(err) } on failure,\n * // { type: \"Ok\", value: Right(user) } on success\n */\n attempt(): IO<never, Either<E, A>> {\n return this.foldM<never, Either<E, A>>(\n (e) => IO.pure(Left.pure(e)),\n (a) => IO.pure(Right.pure(a))\n );\n }\n\n /**\n * Discards both success and failure. The resulting IO runs purely for its\n * side effects and can never fail. Equivalent to ZIO's `ignore`, or Cats'\n * `attempt.void`.\n *\n * Useful for \"best-effort\" fan-out patterns where each branch taps its\n * outcome but must not abort siblings on failure — e.g. parallel tile loads\n * on a dashboard where a missing endpoint should skip that tile without\n * failing the whole fetch.\n *\n * @returns {IO<never, void>} A non-failing IO producing `undefined`.\n *\n * @example\n * await IO.parMapN(\n * UserService.prefetch(id).tap(cache.set).ignore(),\n * SessionService.touch().ignore(),\n * () => undefined,\n * ).unsafeRun();\n */\n ignore(): IO<never, void> {\n return this.foldM<never, void>(\n () => IO.unit,\n () => IO.unit\n );\n }\n\n /**\n * Executes the computation described by this IO and returns the result.\n * The interpreter walks the ADT tree using an explicit stack (trampoline),\n * ensuring stack safety for arbitrarily deep chains.\n *\n * @returns {Promise<Err<E> | Ok<A>>} The result of the computation.\n *\n * @example\n * const result = await IO.lift(() => 42).unsafeRun();\n * // result: { type: \"Ok\", value: 42 }\n */\n async unsafeRun(): Promise<Err<E> | Ok<A>> {\n return interpret(this[NODE]) as Promise<Ok<A> | Err<E>>;\n }\n\n /**\n * Executes the IO and folds both outcomes (success and error) into a single type.\n * This is a terminal operation — it runs the computation and returns a plain value.\n *\n * @template B The result type after folding.\n * @param {(e: E) => B} onErr Handler for the error case.\n * @param {(a: A) => B} onOk Handler for the success case.\n * @returns {Promise<B>} The folded result.\n *\n * @example\n * const message = await IO.lift(() => 42).fold(\n * err => `Failed: ${err}`,\n * val => `Got: ${val}`\n * );\n * // message: \"Got: 42\"\n */\n async fold<B>(onErr: (e: E) => B, onOk: (a: A) => B): Promise<B> {\n const result = await this.unsafeRun();\n return result.type === \"Ok\" ? onOk(result.value) : onErr(result.error);\n }\n\n /**\n * Executes the IO and returns the success value, or `null` if the computation fails.\n *\n * Note: if `A` itself can be `null`, the return value is ambiguous — a `null` result\n * could mean either \"succeeded with null\" or \"failed.\" Use `unsafeRun()` or `fold`\n * when the distinction matters.\n *\n * @returns {Promise<A | null>} The success value or null.\n *\n * @example\n * const value = await IO.lift(() => 42).getOrNull(); // 42\n * const nope = await IO.fail(\"err\").getOrNull(); // null\n */\n async getOrNull(): Promise<A | null> {\n const result = await this.unsafeRun();\n return result.type === \"Ok\" ? result.value : null;\n }\n\n /**\n * Executes the IO and returns the success value, or evaluates the provided\n * default function on error. The default is lazy to avoid unnecessary computation.\n *\n * @param {() => A} defaultValue A function that produces the fallback value.\n * @returns {Promise<A>} The success value or the default.\n *\n * @example\n * const value = await IO.fail(\"err\").getOrElse(() => 0); // 0\n */\n async getOrElse(defaultValue: () => A): Promise<A> {\n const result = await this.unsafeRun();\n return result.type === \"Ok\" ? result.value : defaultValue();\n }\n\n /**\n * Executes the IO and returns the success value, or applies the handler\n * function to the error to produce a fallback value.\n *\n * @param {(error: E) => A} handler A function that transforms the error into a success value.\n * @returns {Promise<A>} The success value or the handled error.\n *\n * @example\n * const value = await IO.fail(new Error(\"boom\"))\n * .getOrHandleErr(e => `Handled: ${e.message}`);\n * // value: \"Handled: boom\"\n */\n async getOrHandleErr(handler: (error: E) => A): Promise<A> {\n const result = await this.unsafeRun();\n return result.type === \"Ok\" ? result.value : handler(result.error);\n }\n\n /**\n * Retries this IO when the condition is met, using the given scheduling policy.\n * The operation is retried with increasing delay based on the policy's factor and jitter settings.\n *\n * If the operation exceeds the retry limit, a `RetryError` is thrown.\n * If the condition is not met, a `ConditionalRetryError` is thrown.\n * Both are transformed through `liftE` into the error type `E`.\n *\n * @param {(error: E) => boolean} condition Predicate on the error — retry only when this returns true.\n * @param {(error: Error) => E} liftE Transforms schedule errors (e.g. RetryError, TimeoutError) into E.\n * @param {Policy} [policy] Scheduling policy (defaults to 3 retries, 1.2x backoff, 1s delay).\n * @returns {IO<E, A>} A new IO that wraps the retry logic.\n *\n * @example\n * const io = IO.lift(() => fetchData())\n * .retryIf(\n * err => err instanceof NetworkError,\n * e => new AppError(e.message),\n * { recurs: 5, delay: 1000, factor: 2 }\n * );\n */\n retryIf(condition: (error: E) => boolean, liftE: (error: Error) => E, policy: Policy = defaultPolicy()): IO<E, A> {\n return IO.lift<E, Schedule>(\n () => new Schedule(policy),\n (e: unknown) => liftE(e instanceof Error ? e : new Error(String(e)))\n ).flatMap((scheduler) => scheduler.retryIf(this, condition, liftE));\n }\n\n /**\n * Applies a timeout to this IO. If the computation does not complete within `ms`\n * milliseconds, it is cancelled and the error produced by `onTimeout` is returned\n * in the error channel. If the computation completes before the deadline, the\n * timeout timer is cleared and the result is returned normally.\n *\n * The timeout error type `F` is unioned with the original error type `E`,\n * so the caller must handle both. The underlying computation is cooperatively\n * cancelled via `AbortSignal` when the timeout fires.\n *\n * This is a first-class replacement for the verbose `IO.race` workaround:\n * ```typescript\n * // Before — manual race\n * IO.race(\n * operation,\n * IO.lift(async () => { await delay(5000); throw new TimeoutError(); })\n * )\n *\n * // After — first-class combinator\n * operation.timeout(5000, () => new TimeoutError('Exceeded 5s'))\n * ```\n *\n * @template F The timeout error type.\n * @param {number} ms The timeout duration in milliseconds.\n * @param {() => F} onTimeout A thunk that produces the timeout error value.\n * @returns {IO<E | F, A>} A new IO that fails with `F` if the timeout elapses.\n *\n * @example\n * const io = IO.lift(() => fetch('/api/slow'))\n * .timeout(5000, () => new TimeoutError('Request exceeded 5s'));\n *\n * @example\n * // Composable with mapErr to unify error types\n * const io = fetchUser(id)\n * .timeout(3000, () => ({ code: 'TIMEOUT', message: 'User fetch timed out' }))\n * .mapErr(e => normalizeError(e));\n */\n timeout<F>(ms: number, onTimeout: () => F): IO<E | F, A> {\n const node = this[NODE];\n return IO.lift<E | F, A>(\n (signal?: AbortSignal) => {\n return new Promise<A>((resolve, reject) => {\n const controller = new AbortController();\n\n // Link parent signal — clean up listener when settled\n let unlinkParent: (() => void) | undefined;\n if (signal) {\n if (signal.aborted) {\n controller.abort();\n } else {\n const onAbort = () => controller.abort();\n signal.addEventListener(\"abort\", onAbort, { once: true });\n unlinkParent = () => signal.removeEventListener(\"abort\", onAbort);\n }\n }\n\n let settled = false;\n const settle = () => {\n settled = true;\n if (unlinkParent) unlinkParent();\n };\n\n const timer = setTimeout(() => {\n if (settled) return;\n settle();\n controller.abort(); // cancel the underlying IO\n reject(ioEscape(onTimeout()));\n }, ms);\n\n interpret(node, controller.signal).then((result) => {\n if (settled) return;\n settle();\n clearTimeout(timer);\n if (result.type === \"Ok\") resolve(result.value);\n else if (result.type === \"Cancelled\") reject({ [IO_CANCELLED]: true });\n else reject(ioEscape(result.error));\n });\n\n // Clear timer on cancellation to avoid retaining the closure\n controller.signal.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n },\n { once: true }\n );\n });\n },\n (e: unknown) => {\n if (isIOCancelled(e)) throw e;\n if (isIOEscape(e)) return e.error as E | F;\n return e as E | F;\n }\n );\n }\n\n /**\n * Starts this IO as a background computation, returning a `Fiber` handle.\n * The fiber can be joined (await result) or cancelled.\n *\n * `fork()` returns `IO<never, Fiber<E, A>>` — it is lazy and composable.\n * The computation only starts when the outer IO is executed.\n *\n * @returns {IO<never, Fiber<E, A>>} An IO that, when executed, starts this IO and returns a Fiber.\n *\n * @example\n * const io = IO.Do<AppError, string>(async bind => {\n * const fiber = await bind(longRunningTask.fork());\n * // ... do other work ...\n * const result = await fiber.join();\n * return result;\n * });\n */\n fork(): IO<never, Fiber<E, A>> {\n const node = this[NODE];\n return IO.lift(() => {\n const controller = new AbortController();\n const promise = interpret(node, controller.signal);\n return {\n join: () => promise,\n cancel: async () => {\n controller.abort();\n await promise.catch(() => {});\n },\n signal: controller.signal,\n } as Fiber<E, A>;\n });\n }\n\n /**\n * Runs multiple IOs in parallel and combines their results with a function.\n * All IOs are executed concurrently via `Promise.all`. If any IO fails,\n * all errors are collected into a `NonEmptyList`.\n *\n * Supports heterogeneous error types — each IO may have a different error type `E`,\n * and the resulting error is the union of all error types.\n *\n * The last argument is always the combiner function that receives the success values\n * in the same order as the IO arguments.\n *\n * @example\n * const io = IO.parMapN(\n * IO.lift(() => fetchUser()),\n * IO.lift(() => fetchOrders()),\n * (user, orders) => ({ user, orders })\n * );\n */\n static parMapN<E1, E2, A1, A2, R>(\n io1: IO<E1, A1>,\n io2: IO<E2, A2>,\n f: (a1: A1, a2: A2) => R\n ): IO<NonEmptyList<E1 | E2>, R>;\n static parMapN<E1, E2, E3, A1, A2, A3, R>(\n io1: IO<E1, A1>,\n io2: IO<E2, A2>,\n io3: IO<E3, A3>,\n f: (a1: A1, a2: A2, a3: A3) => R\n ): IO<NonEmptyList<E1 | E2 | E3>, R>;\n static parMapN<E1, E2, E3, E4, A1, A2, A3, A4, R>(\n io1: IO<E1, A1>,\n io2: IO<E2, A2>,\n io3: IO<E3, A3>,\n io4: IO<E4, A4>,\n f: (a1: A1, a2: A2, a3: A3, a4: A4) => R\n ): IO<NonEmptyList<E1 | E2 | E3 | E4>, R>;\n static parMapN<E1, E2, E3, E4, E5, A1, A2, A3, A4, A5, R>(\n io1: IO<E1, A1>,\n io2: IO<E2, A2>,\n io3: IO<E3, A3>,\n io4: IO<E4, A4>,\n io5: IO<E5, A5>,\n f: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => R\n ): IO<NonEmptyList<E1 | E2 | E3 | E4 | E5>, R>;\n static parMapN<E1, E2, E3, E4, E5, E6, A1, A2, A3, A4, A5, A6, R>(\n io1: IO<E1, A1>,\n io2: IO<E2, A2>,\n io3: IO<E3, A3>,\n io4: IO<E4, A4>,\n io5: IO<E5, A5>,\n io6: IO<E6, A6>,\n f: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => R\n ): IO<NonEmptyList<E1 | E2 | E3 | E4 | E5 | E6>, R>;\n static parMapN(...ops: any[]): IO<NonEmptyList<any>, any> {\n if (ops.length < 3) {\n return IO.fail(\n NonEmptyList._unsafeFromArray([\n new Error(\"IO.parMapN requires at least two IO arguments and a combiner function\"),\n ])\n );\n }\n const input = ops.slice(0, -1) as IO<any, any>[];\n const combiner = ops[ops.length - 1] as (...args: any[]) => any;\n\n return IO.lift<NonEmptyList<any>, any>(\n async (signal?: AbortSignal) => {\n const results = await Promise.all(input.map((io) => interpret(io[NODE], signal)));\n\n // If any cancelled, propagate cancellation\n if (results.some((r) => r.type === \"Cancelled\")) {\n ioCancelled();\n }\n\n const errors = results.filter((r): r is Err<any> => r.type === \"Err\").map((r) => r.error);\n\n if (errors.length > 0) {\n throw ioEscape(NonEmptyList._unsafeFromArray(errors));\n }\n\n const values = results.filter((r): r is Ok<any> => r.type === \"Ok\").map((r) => r.value);\n\n return combiner(...values);\n },\n (e: unknown) => {\n if (isIOEscape(e)) return e.error as NonEmptyList<any>;\n return NonEmptyList._unsafeFromArray([e]);\n }\n );\n }\n\n /**\n * Races multiple IOs concurrently, returning the result of the first one to succeed.\n * If all IOs fail, returns a `NonEmptyList` of all errors in the order they were provided.\n *\n * This is useful for implementing fallback strategies where you want the fastest\n * successful response from multiple sources.\n *\n * @template E The error type of the individual IOs.\n * @template A The success type (must be the same for all IOs).\n * @param {...IO<E, A>} ops The IO operations to race.\n * @returns {IO<NonEmptyList<E>, A>} An IO that succeeds with the first result or fails with all errors.\n *\n * @example\n * const io = IO.race(\n * IO.lift(() => fetchFromPrimary()),\n * IO.lift(() => fetchFromFallback()),\n * );\n */\n static race<E, A>(...ops: IO<E, A>[]): IO<NonEmptyList<E>, A> {\n if (ops.length === 0) {\n return IO.fail(\n NonEmptyList._unsafeFromArray([new Error(\"IO.race requires at least one IO argument\") as unknown as E])\n );\n }\n\n return IO.lift<NonEmptyList<E>, A>(\n (signal?: AbortSignal) => {\n return new Promise<A>((resolve, reject) => {\n const controller = new AbortController();\n\n // Link parent signal — clean up listener when settled\n let unlinkParent: (() => void) | undefined;\n if (signal) {\n if (signal.aborted) {\n controller.abort();\n } else {\n const onAbort = () => controller.abort();\n signal.addEventListener(\"abort\", onAbort, { once: true });\n unlinkParent = () => signal.removeEventListener(\"abort\", onAbort);\n }\n }\n\n let completed = 0;\n let settled = false;\n const errors: (E | undefined)[] = new Array(ops.length);\n\n const settle = () => {\n settled = true;\n if (unlinkParent) unlinkParent();\n };\n\n ops.forEach((io, index) => {\n interpret(io[NODE], controller.signal).then((result) => {\n if (settled) return;\n if (result.type === \"Ok\") {\n settle();\n controller.abort(); // Cancel losers\n resolve(result.value);\n } else if (result.type === \"Err\") {\n errors[index] = result.error;\n completed++;\n if (completed === ops.length) {\n settle();\n // Filter out undefined holes from cancelled entries\n const realErrors = errors.filter((e): e is E => e !== undefined);\n if (realErrors.length > 0) {\n reject(ioEscape(NonEmptyList._unsafeFromArray(realErrors)));\n } else {\n // All completed but no real errors (shouldn't happen), propagate cancellation\n reject({ [IO_CANCELLED]: true });\n }\n }\n } else {\n // Cancelled\n completed++;\n if (completed === ops.length && !settled) {\n settle();\n // Filter out undefined holes from cancelled entries\n const realErrors = errors.filter((e): e is E => e !== undefined);\n if (realErrors.length > 0) {\n reject(ioEscape(NonEmptyList._unsafeFromArray(realErrors)));\n } else {\n // All cancelled — propagate cancellation, not a fake error\n reject({ [IO_CANCELLED]: true });\n }\n }\n }\n });\n });\n });\n },\n (e: unknown) => {\n if (isIOCancelled(e)) throw e;\n if (isIOEscape(e)) return e.error as NonEmptyList<E>;\n return NonEmptyList._unsafeFromArray([e as E]);\n }\n );\n }\n\n /**\n * Monadic do-notation. Sequences IO operations using an imperative-style\n * `bind` function that unwraps IO values or short-circuits on the first error.\n *\n * Inside the `operation` callback, call `bind(io)` to execute an IO and extract its\n * success value. If any bound IO fails, the entire `Do` short-circuits with that error —\n * subsequent `bind` calls are not executed.\n *\n * Uses an `IOEscape` sentinel internally to preserve the typed error `E` through\n * JavaScript's throw/catch mechanism, ensuring the error channel remains type-safe.\n *\n * When `liftE` is provided, non-IO exceptions thrown inside the operation block\n * (e.g. programming errors, unexpected throws) are transformed into the error type `E`\n * via `liftE`, closing the type hole. Without `liftE`, such exceptions pass through\n * untyped — use with care.\n *\n * @template E The error type shared by all bound IO operations.\n * @template A The final success type produced by the comprehension.\n * @param {(bind: <B>(effect: IO<E, B>) => Promise<B>) => Promise<A>} operation\n * An async function that receives a `bind` callback for unwrapping IO values.\n * @param {(e: unknown) => E} [liftE] Optional function to transform non-IO exceptions into E.\n * @returns {IO<E, A>} An IO that, when executed, runs the comprehension.\n *\n * @example\n * const io = IO.Do<AppError, number>(async bind => {\n * const user = await bind(fetchUser(userId));\n * const orders = await bind(fetchOrders(user.id));\n * return orders.length;\n * });\n */\n static Do<E, A>(\n operation: (bind: <B>(effect: IO<E, B>) => Promise<B>) => Promise<A>,\n liftE?: (e: unknown) => E\n ): IO<E, A> {\n const userLiftE = liftE;\n return IO.lift<E, A>(\n async (signal?: AbortSignal) => {\n const bind = async <B>(eff: IO<E, B>): Promise<B> => {\n const result = await interpret(eff[NODE], signal);\n if (result.type === \"Ok\") {\n return result.value;\n }\n if (result.type === \"Cancelled\") {\n ioCancelled(); // throws\n }\n throw ioEscape(result.error);\n };\n return await operation(bind);\n },\n (e: unknown): E => {\n if (isIOCancelled(e)) throw e; // re-throw, don't process through liftE\n if (isIOEscape(e)) return e.error as E;\n if (userLiftE) return userLiftE(e);\n return e as E;\n }\n );\n }\n\n /**\n * Sequentially executes a function over each item, collecting results into an array.\n * Fail-fast: if any invocation fails, the remaining items are not processed and the\n * error is returned immediately.\n *\n * @template E The error type.\n * @template A The input item type.\n * @template B The output type for each item.\n * @param {A[]} items The items to traverse.\n * @param {(a: A) => IO<E, B>} f A function that produces an IO for each item.\n * @returns {IO<E, List<B>>} An IO that succeeds with all results as a List, or fails with the first error.\n *\n * @example\n * const io = IO.traverse([1, 2, 3], n => IO.lift(() => n * 2));\n * // result: { type: \"Ok\", value: List [2, 4, 6] }\n */\n static traverse<E, A, B>(items: A[], f: (a: A) => IO<E, B>): IO<E, List<B>> {\n return IO.Do<E, List<B>>(async (bind) => {\n const results: B[] = [];\n for (const item of items) {\n results.push(await bind(f(item)));\n }\n return List._unsafeFromArray(results);\n });\n }\n\n /**\n * Executes a function over each item in parallel, collecting all results or all errors.\n * Unlike `traverse`, all items are processed concurrently. If any fail, all errors\n * are collected into a `NonEmptyList`.\n *\n * @template E The error type.\n * @template A The input item type.\n * @template B The output type for each item.\n * @param {A[]} items The items to traverse in parallel.\n * @param {(a: A) => IO<E, B>} f A function that produces an IO for each item.\n * @returns {IO<NonEmptyList<E>, List<B>>} An IO that succeeds with all results as a List, or fails with all errors.\n *\n * @example\n * const io = IO.parTraverse([1, 2, 3], n => IO.lift(() => n * 2));\n * // result: { type: \"Ok\", value: List [2, 4, 6] }\n */\n static parTraverse<E, A, B>(items: A[], f: (a: A) => IO<E, B>): IO<NonEmptyList<E>, List<B>> {\n return IO.lift<NonEmptyList<E>, List<B>>(\n async (signal?: AbortSignal) => {\n const results = await Promise.all(items.map((item) => interpret(f(item)[NODE], signal)));\n\n // If any cancelled, propagate cancellation\n if (results.some((r) => r.type === \"Cancelled\")) {\n ioCancelled();\n }\n\n const errors = results.filter((r): r is Err<E> => r.type === \"Err\").map((r) => r.error);\n\n if (errors.length > 0) {\n throw ioEscape(NonEmptyList._unsafeFromArray(errors));\n }\n\n return List._unsafeFromArray(results.filter((r): r is Ok<B> => r.type === \"Ok\").map((r) => r.value));\n },\n (e: unknown) => {\n if (isIOEscape(e)) return e.error as NonEmptyList<E>;\n return NonEmptyList._unsafeFromArray([e as E]);\n }\n );\n }\n\n /**\n * Sequentially executes an array of IOs, collecting results into an array.\n * Equivalent to `traverse(ios, x => x)`. Fail-fast on the first error.\n *\n * @template E The error type.\n * @template A The success type of each IO.\n * @param {IO<E, A>[]} ios The IO operations to sequence.\n * @returns {IO<E, List<A>>} An IO that succeeds with all results as a List, or fails with the first error.\n *\n * @example\n * const io = IO.sequence([IO.lift(() => 1), IO.lift(() => 2), IO.lift(() => 3)]);\n * // result: { type: \"Ok\", value: List [1, 2, 3] }\n */\n static sequence<E, A>(ios: IO<E, A>[]): IO<E, List<A>> {\n return IO.traverse(ios, (io) => io);\n }\n\n /**\n * Executes an array of IOs in parallel, collecting all results or all errors.\n * Equivalent to `parTraverse(ios, x => x)`.\n *\n * @template E The error type.\n * @template A The success type of each IO.\n * @param {IO<E, A>[]} ios The IO operations to execute in parallel.\n * @returns {IO<NonEmptyList<E>, List<A>>} An IO that succeeds with all results as a List, or fails with all errors.\n *\n * @example\n * const io = IO.parSequence([IO.lift(() => 1), IO.lift(() => 2), IO.lift(() => 3)]);\n * // result: { type: \"Ok\", value: List [1, 2, 3] }\n */\n static parSequence<E, A>(ios: IO<E, A>[]): IO<NonEmptyList<E>, List<A>> {\n return IO.parTraverse(ios, (io) => io);\n }\n}\n","/**\n * `Eval` represents a deferred computation, which allows operations to be delayed, chained,\n * and lazily evaluated. It provides a foundation for creating different types of deferred operations\n * that can be evaluated on demand.\n *\n * Its primary goal is to facilitate the construction and manipulation of computations in a way\n * that allows for efficient and flexible execution strategies. It can create immediate, deferred,\n * and lazy computations, and compose them using monadic operations.\n *\n * @template A The type of the value that this computation produces.\n */\nexport abstract class Eval<A> {\n /**\n * Retrieves the value of the operation.\n * This is an internal method used by the trampoline interpreter. External code should\n * always use `evaluate()` instead — calling `value()` directly on `Map` or `FlatMap`\n * nodes throws an `EvaluationError`.\n *\n * @internal\n * @returns {A} The value produced by the operation.\n */\n protected abstract value(): A;\n\n /**\n * Creates a deferred operation that will be evaluated later.\n * The provided function is not executed until the value of the operation is needed.\n *\n * This method is useful for deferring expensive computations until their results are required,\n * thereby improving performance and resource utilization.\n *\n * @template A The type of the value that the operation produces.\n * @param {() => A} f The function to defer, which produces the operation's value when called.\n * @returns {Eval<A>} A new deferred operation.\n *\n * @example\n * // Defers the computation of a value\n * const deferredEval = Eval.defer(() => {\n * console.log(\"Computing value...\");\n * return 42;\n * });\n *\n * // The value is not computed until we call `evaluate`\n * console.log(deferredEval.evaluate()); // Logs \"Computing value...\" then 42\n */\n static defer<A>(f: () => A): Eval<A> {\n return new Deferred(f);\n }\n\n /**\n * Creates an immediate operation with a given value.\n * The provided value is available immediately without any deferred computation.\n *\n * This method is useful for wrapping a value in an `Eval` instance when the value is already\n * computed, and the evaluation does not need to be deferred.\n *\n * @template A The type of the value that the operation produces.\n * @param {A} value The value to wrap in an immediate operation.\n * @returns {Eval<A>} A new immediate operation.\n *\n * @example\n * // Wraps an immediate value in an Eval instance\n * const immediateEval = Eval.pure(42);\n *\n * // The value is available immediately\n * console.log(immediateEval.evaluate()); // Logs 42\n */\n static pure<A>(value: A): Eval<A> {\n return new Now(value);\n }\n\n /**\n * Creates a lazy operation that will be evaluated once when needed.\n * The provided function is evaluated the first time the value is requested, and the result is cached\n * for subsequent accesses.\n *\n * This method is useful for deferring the computation until it is needed, while ensuring that the computation\n * is performed at most once, thereby combining the benefits of deferred and memoized evaluation.\n *\n * @template A The type of the value that the operation produces.\n * @param {() => A} f The function to lazily evaluate, which produces the operation's value when called.\n * @returns {Eval<A>} A new lazy operation.\n *\n * @example\n * // Lazily computes a value\n * const lazyEval = Eval.lazy(() => {\n * console.log(\"Computing value...\");\n * return 42;\n * });\n *\n * // The value is not computed until `evaluate` is called the first time\n * console.log(lazyEval.evaluate()); // Logs \"Computing value...\" then 42\n *\n * // Subsequent calls do not recompute the value\n * console.log(lazyEval.evaluate()); // Logs 42\n */\n static lazy<A>(f: () => A): Eval<A> {\n return new Lazy(f);\n }\n\n /**\n * Transforms the result of the operation using a given function.\n * The provided function is applied to the value produced by this operation, and the result is wrapped\n * in a new `Eval` instance.\n *\n * It allows for chaining operations in a functional style, enabling the transformation of values\n * as part of a sequence of computations.\n *\n * @template A The type of the result before transformation.\n * @template B The type of the result after transformation.\n * @param {(a: A) => B} f The transformation function that takes a value of type `A` and returns a value of type `B`.\n * @returns {Eval<B>} A new operation representing the transformed result.\n *\n * @example\n * // Creates an immediate operation with an initial value\n * const immediateEval = Eval.now(42);\n *\n * // Transforms the value by adding 1\n * const mappedEval = immediateEval.map(value => value + 1);\n *\n * // Evaluates the transformed operation\n * console.log(mappedEval.evaluate()); // Logs 43\n */\n map<B>(f: (a: A) => B): Eval<B> {\n return new Map(this, f);\n }\n\n /**\n * Composes this operation with another operation.\n * The provided function takes the result of this operation and returns a new `Eval` instance,\n * allowing for the creation of a sequence of dependent computations.\n *\n * This method is useful for chaining multiple computations that may have dependencies on each other,\n * enabling a monadic style of composition where each step can produce a new deferred computation.\n *\n * @template A The type of the result before composition.\n * @template B The type of the result of the composed operation.\n * @param {(a: A) => Eval<B>} f The function to compose with, which takes a value of type `A`\n * and returns a new `Eval` instance producing a value of type `B`.\n * @returns {Eval<B>} A new operation representing the composed result.\n *\n * @example\n * // Creates an immediate operation with an initial value\n * const immediateEval = Eval.now(42);\n *\n * // Composes the initial operation with another operation that adds 1 and wraps it in Eval\n * const flatMappedEval = immediateEval.flatMap(value => Eval.now(value + 1));\n *\n * // Evaluates the composed operation\n * console.log(flatMappedEval.evaluate()); // Logs 43\n */\n flatMap<B>(f: (a: A) => Eval<B>): Eval<B> {\n return new FlatMap(this, f);\n }\n\n /**\n * Evaluates the operation, including any composed operations.\n * It uses an iterative approach with a stack to handle nested operations, ensuring\n * that the computation is performed in the correct order and avoiding stack overflow from deep recursion.\n *\n * It is essential for obtaining the final result of an `Eval` computation, especially when\n * multiple operations are chained together.\n *\n * @template A The type of the final result of the computation.\n * @returns {A} The final result of the computation.\n * @throws {EvaluationError} If there is an unexpected issue during evaluation, such as an undefined function in the stack.\n *\n * @example\n * // Creates a deferred operation\n * const deferredEval = Eval.defer(() => 21);\n *\n * // Composes the deferred operation with another operation\n * const composedEval = deferredEval.flatMap(value => Eval.now(value * 2));\n *\n * // Evaluates the composed operation\n * console.log(composedEval.evaluate()); // Logs 42\n */\n /* eslint-disable @typescript-eslint/no-this-alias */\n evaluate(): A {\n let current: Eval<A> = this;\n const stack: Array<(a: any) => Eval<A>> = [];\n\n while (true) {\n if (current instanceof FlatMap) {\n const inner = current.first;\n if (inner instanceof FlatMap || inner instanceof Map) {\n stack.push(current.f);\n current = inner;\n } else {\n current = current.f(inner.value());\n }\n } else if (current instanceof Map) {\n // Collect consecutive Map functions and apply iteratively\n const maps: Array<(a: any) => any> = [current.f];\n let inner: Eval<any> = current.first;\n while (inner instanceof Map) {\n maps.push(inner.f);\n inner = inner.first;\n }\n const applyMaps = (val: any) => {\n for (let i = maps.length - 1; i >= 0; i--) {\n val = maps[i](val);\n }\n return val;\n };\n if (inner instanceof FlatMap) {\n stack.push((a) => new Now(applyMaps(a)));\n current = inner;\n } else {\n const result = applyMaps(inner.value());\n if (stack.length === 0) {\n return result;\n }\n current = stack.pop()!(result);\n }\n } else {\n const result = current.value();\n if (stack.length === 0) {\n return result;\n }\n current = stack.pop()!(result);\n }\n }\n }\n}\n\n/**\n * Represents an immediate computation. The value is precomputed and available immediately without any delay.\n *\n * The `Now` class is useful when you have a value that is already computed, and you want to wrap it\n * in an `Eval` instance to integrate with other deferred computations.\n *\n * @template A The type of the value that this computation produces.\n */\nclass Now<A> extends Eval<A> {\n /**\n * Creates an instance of `Now` with a given value.\n */\n constructor(private readonly _value: A) {\n super();\n }\n\n /**\n * Retrieves the immediate value of the computation.\n *\n * @returns {A} The precomputed value.\n *\n * @example\n * // Creates an immediate computation with the value 42\n * const immediateEval = new Now(42);\n *\n * // Retrieves the value immediately\n * console.log(immediateEval.value()); // Logs 42\n */\n value(): A {\n return this._value;\n }\n}\n\n/**\n * Represents a deferred computation. The computation is not performed until the value is explicitly requested.\n * The `Deferred` class is useful for deferring expensive or time-consuming computations until their results are needed.\n *\n * @template A The type of the value that this computation produces.\n */\nclass Deferred<A> extends Eval<A> {\n /**\n * Creates an instance of `Deferred` with a given f function.\n *\n * @param {() => A} f The function to defer, which produces the computation's value when called.\n */\n constructor(private readonly f: () => A) {\n super();\n }\n\n /**\n * Performs the deferred computation and returns the result.\n *\n * @returns {A} The value produced by the deferred computation.\n *\n * @example\n * // Creates a deferred computation\n * const deferredEval = new Deferred(() => {\n * console.log(\"Computing value...\");\n * return 42;\n * });\n *\n * // The computation is not performed until `value` is called\n * console.log(deferredEval.value()); // Logs \"Computing value...\" then 42\n */\n value(): A {\n return this.f();\n }\n}\n\n/**\n * Represents a lazy computation that will be evaluated once.\n * The provided function is evaluated the first time the value is requested, and the result is cached\n * for subsequent accesses.\n *\n * The `Lazy` class is useful for deferring the computation until it is needed, while ensuring that the computation\n * is performed at most once. This combines the benefits of deferred and memoized evaluation.\n *\n * @template A The type of the value that this computation produces.\n */\nclass Lazy<A> extends Eval<A> {\n private _value?: A;\n private _evaluated = false;\n\n /**\n * Creates an instance of `Lazy` with a given f function.\n *\n * @param {() => A} f The function to lazily evaluate, which produces the operation's value when called.\n */\n constructor(private readonly f: () => A) {\n super();\n }\n\n /**\n * Performs the lazy computation if it has not been done yet, caches the result, and returns the value.\n *\n * @returns {A} The value produced by the lazy computation.\n *\n * @example\n * // Creates a lazy computation\n * const lazyEval = new Lazy(() => {\n * console.log(\"Computing value...\");\n * return 42;\n * });\n *\n * // The computation is not performed until `value` is called the first time\n * console.log(lazyEval.value()); // Logs \"Computing value...\" then 42\n *\n * // Subsequent calls do not recompute the value\n * console.log(lazyEval.value()); // Logs 42\n */\n value(): A {\n if (!this._evaluated) {\n this._value = this.f();\n this._evaluated = true;\n }\n return this._value!;\n }\n}\n\n/**\n * Represents a computation that is the result of a flatMap operation.\n * A `FlatMap` allows for the composition of multiple computations where each computation\n * can depend on the result of the previous one.\n *\n * The `FlatMap` class is used internally to chain computations in a monadic style. It extends the `Eval`\n * abstract class and implements the `value` method to throw an error, as a `FlatMap` should not be\n * directly evaluated. Instead, its evaluation is handled by the `Eval` class's `evaluate` method.\n *\n * @template A The type of the value produced by the first computation.\n * @template B The type of the value produced by the composed computation.\n */\nclass FlatMap<A, B> extends Eval<B> {\n /**\n * Creates an instance of `FlatMap` with a given initial computation and a function to compose with.\n *\n * @param {Eval<A>} first The initial computation.\n * @param {(a: A) => Eval<B>} f The function to compose with, which takes a value of type `A`\n * and returns a new `Eval` instance producing a value of type `B`.\n */\n constructor(\n public readonly first: Eval<A>,\n public readonly f: (a: A) => Eval<B>\n ) {\n super();\n }\n\n /**\n * This method should not be called directly. It is implemented to throw an error because\n * a `FlatMap` should not be evaluated directly. Instead, its evaluation is managed by the `Eval` class's\n * `evaluate` method.\n *\n * @throws {EvaluationError} Always throws an error indicating that `FlatMap` should not be evaluated directly.\n */\n value(): B {\n throw new EvaluationError(\"FlatMap should not be evaluated directly\");\n }\n}\n\n/**\n * Represents a transformation of a computation's result. Unlike `FlatMap`, the mapping function\n * returns a plain value rather than an `Eval` instance. Consecutive `Map` nodes are fused into\n * a single composed function during evaluation, avoiding intermediate allocations and stack growth.\n *\n * @template A The type of the value produced by the source computation.\n * @template B The type of the value after transformation.\n */\nclass Map<A, B> extends Eval<B> {\n constructor(\n public readonly first: Eval<A>,\n public readonly f: (a: A) => B\n ) {\n super();\n }\n\n value(): B {\n throw new EvaluationError(\"Map should not be evaluated directly\");\n }\n}\n\n/**\n * Represents an error that occurs during the evaluation of a computation.\n *\n * The `EvaluationError` class extends the standard `Error` class to provide additional context\n * specific to errors encountered during the evaluation of `Eval` computations. This class includes\n * the original error that caused the evaluation to fail, allowing for more detailed error handling\n * and debugging.\n *\n * @template E The type of the error details.\n */\nexport class EvaluationError<E> extends Error {\n /**\n * Creates an instance of `EvaluationError` with the specified error details.\n *\n * @param {E} error The details of the error that occurred during evaluation.\n */\n constructor(readonly error: E) {\n super();\n this.name = \"EvaluationError\";\n }\n}\n","/**\n * The `Reader` type is a construct that allows for\n * dependency injection without side effects, promoting cleaner and more\n * maintainable code. It encapsulates an environment and provides it implicitly\n * to functions that require it, avoiding the need to pass dependencies\n * explicitly through every layer of an application.\n *\n * The `Reader` type supports various operations, including mapping,\n * flatMapping, lifting functions into the Reader context, and combining\n * multiple Reader instances. It is particularly useful in scenarios where\n * managing dependencies such as configurations or shared resources can become\n * cumbersome and error-prone.\n *\n * Type Parameters:\n * - `R`: The type of the environment that the Reader depends on.\n * - `A`: The type of the value produced by the Reader computation.\n *\n * Usage Example:\n * ```typescript\n * // Define an environment type\n * type Env = { apiEndpoint: string };\n *\n * // Define a Reader that fetches data using the environment's API endpoint\n * const fetchData = Reader.ask<Env>().flatMap(env =>\n * Reader.pure(fetch(`${env.apiEndpoint}/data`).then(response => response.json()))\n * );\n *\n * // Define a function to run the Reader with a specific environment\n * const runFetchData = async (env: Env) => {\n * const data = await fetchData.run(env);\n * console.log(data); // Handle fetched data\n * };\n *\n * // Example environment\n * const env: Env = { apiEndpoint: 'https://api.example.com' };\n *\n * // Execute the function\n * runFetchData(env);\n * ```\n */\nexport class Reader<R, A> {\n /**\n * Initializes a new `Reader` instance.\n *\n * A `Reader` represents a computation that needs an environment `R` to produce\n * a value of type `A`. This makes it easier to manage dependencies and side effects\n * in a functional programming style, promoting cleaner and more maintainable code.\n *\n * @param {function(R): A} f - A function that takes an environment of type `R`\n * and returns a value of type `A`.\n *\n * @example\n * // Define an environment type\n * type Env = { apiEndpoint: string };\n *\n * // Define a function that uses the environment to fetch data\n * const fetchData = (env: Env) => fetch(`${env.apiEndpoint}/data`).then(response => response.json());\n *\n * // Create a Reader instance with the function\n * const reader = new Reader(fetchData);\n *\n * // Define an environment\n * const env: Env = { apiEndpoint: 'https://api.example.com' };\n *\n * // Run the Reader with the provided environment\n * reader.run(env).then(data => console.log(data));\n */\n public constructor(private f: (env: R) => A) {}\n\n /**\n * Creates a new `Reader` instance that ignores the environment and always returns\n * the provided value.\n *\n * This is useful for lifting a value into the `Reader` context, allowing\n * you to work with the value in a way that is consistent with other `Reader` computations\n * without requiring any environment.\n *\n * @param value - The value to be returned by the `Reader`.\n * @returns A new `Reader` instance that always returns the provided value.\n *\n * @example\n * // Creating a Reader that always returns the value 42\n * const reader = Reader.pure<number, number>(42);\n *\n * // Running the Reader with any environment will always return 42\n * console.log(reader.run(10)); // 42\n * console.log(reader.run({})); // 42\n */\n static pure<R, A>(value: A): Reader<R, A> {\n return new Reader(() => value);\n }\n\n /**\n * Transforms the result of the `Reader` computation by applying the provided\n * function to its value.\n *\n * This allows you to change the value produced by the `Reader` without\n * altering the environment. It is useful for chaining operations in a functional\n * style, where each step can modify the result of the previous computation.\n *\n * @param f - A function that takes the result of the `Reader` and returns a new value.\n * @returns A new `Reader` instance that applies the transformation function to the result.\n *\n * @example\n * // Creating a Reader that returns the length of a string from the environment\n * const reader = Reader.ask<string>().map(env => env.length);\n *\n * // Running the Reader with an environment string will return its length\n * console.log(reader.run(\"Hello, world!\")); // 13\n * console.log(reader.run(\"TypeScript\")); // 10\n */\n map<B>(f: (a: A) => B): Reader<R, B> {\n return new Reader((env: R) => f(this.run(env)));\n }\n\n /**\n * Chains a new `Reader` computation to the result of the current `Reader`.\n *\n * This method allows you to sequence `Reader` operations, where the result of one\n * computation can determine the next computation. It is useful for creating complex\n * workflows that depend on the environment and previous results.\n *\n * @param f - A function that takes the result of the current `Reader` and returns a new `Reader`.\n * @returns A new `Reader` instance that represents the chained computation.\n *\n * @example\n * // Creating a Reader that fetches data and then processes it\n * const fetchData = Reader.ask<{ apiEndpoint: string }>().flatMap(env =>\n * Reader.pure(fetch(`${env.apiEndpoint}/data`).then(response => response.json()))\n * );\n *\n * const processData = fetchData.flatMap(data =>\n * Reader.pure(data.map(item => item.value))\n * );\n *\n * // Running the Reader with an environment will fetch and process the data\n * processData.run({ apiEndpoint: 'https://api.example.com' }).then(console.log);\n */\n flatMap<B>(f: (a: A) => Reader<R, B>): Reader<R, B> {\n return new Reader((env: R) => f(this.run(env)).run(env));\n }\n\n /**\n * Creates a `Reader` instance that provides access to the environment.\n *\n * This is useful when you need to obtain the environment itself\n * within a `Reader` computation. It returns a `Reader` that, when run, simply\n * returns the environment.\n *\n * @returns A new `Reader` instance that returns the environment.\n *\n * @example\n * // Creating a Reader that returns the environment\n * const reader = Reader.ask<{ apiEndpoint: string }>();\n *\n * // Running the Reader will return the provided environment\n * const env = { apiEndpoint: 'https://api.example.com' };\n * console.log(reader.run(env)); // { apiEndpoint: 'https://api.example.com' }\n *\n * // Combining with map to access a specific part of the environment\n * const apiEndpointReader = reader.map(env => env.apiEndpoint);\n * console.log(apiEndpointReader.run(env)); // 'https://api.example.com'\n */\n static ask<R>(): Reader<R, R> {\n return new Reader((env: R) => env);\n }\n\n /**\n * Lifts a function into the `Reader` context, allowing it to be applied\n * to the result of a `Reader` computation.\n *\n * This static method is useful for transforming the result of a `Reader`\n * using a regular function. It takes a function that operates on a value\n * and returns a new function that operates on a `Reader`.\n *\n * @param f - A function that takes a value and returns a new value.\n * @returns A function that takes a `Reader` and returns a new `Reader` with the transformed result.\n *\n * @example\n * // Define a function to be lifted\n * const toUpperCase = (s: string) => s.toUpperCase();\n *\n * // Create a Reader that reads a string from the environment\n * const reader = Reader.ask<string>();\n *\n * // Lift the function into the Reader context\n * const upperCaseReader = Reader.lift(toUpperCase)(reader);\n *\n * // Running the Reader will apply the function to the environment value\n * console.log(upperCaseReader.run(\"hello\")); // \"HELLO\"\n * console.log(upperCaseReader.run(\"world\")); // \"WORLD\"\n */\n static lift<R, A, B>(f: (a: A) => B): (ra: Reader<R, A>) => Reader<R, B> {\n return (ra: Reader<R, A>) => ra.map(f);\n }\n\n /**\n * Combines multiple `Reader` instances into a single `Reader` that produces a tuple\n * of their results when run with the same environment.\n *\n * This is useful for executing multiple `Reader` computations\n * in parallel and collecting their results into a single value.\n *\n * @param readers - An array of `Reader` instances to be combined.\n * @returns A new `Reader` instance that returns a tuple of the results of the given `Reader` instances.\n *\n * @example\n * // Create multiple Readers that read different values from the environment\n * const readerA = Reader.ask<{ valueA: number, valueB: string, valueC: boolean }>().map(env => env.valueA);\n * const readerB = Reader.ask<{ valueA: number, valueB: string, valueC: boolean }>().map(env => env.valueB);\n * const readerC = Reader.ask<{ valueA: number, valueB: string, valueC: boolean }>().map(env => env.valueC);\n *\n * // Combine the Readers\n * const combinedReader = Reader.parZip(readerA, readerB, readerC);\n *\n * // Running the combined Reader will return a tuple of the results\n * const env = { valueA: 42, valueB: \"hello\", valueC: true };\n * console.log(combinedReader.run(env)); // [42, \"hello\", true]\n */\n static parZip<R, A extends any[]>(...readers: { [K in keyof A]: Reader<R, A[K]> }): Reader<R, A> {\n return new Reader((env: R) => readers.map((reader) => reader.run(env)) as A);\n }\n\n /**\n * Creates a new `Reader` that applies a transformation to the environment before\n * running the provided `Reader` computation.\n *\n * This static method is useful for temporarily modifying the environment for a specific\n * computation, allowing you to adjust the context in which the `Reader` runs without\n * affecting the broader environment.\n *\n * @param f - A function that takes the current environment and returns a modified environment.\n * @param reader - The `Reader` instance to run with the modified environment.\n * @returns A new `Reader` instance that runs the provided `Reader` with the transformed environment.\n *\n * @example\n * // Define an environment type\n * type Env = { apiEndpoint: string, version: string };\n *\n * // Create a Reader that reads the API endpoint from the environment\n * const reader = Reader.ask<Env>().map(env => env.apiEndpoint);\n *\n * // Define a function to modify the environment\n * const upgradeApi = (env: Env) => ({ ...env, version: 'v2' });\n *\n * // Create a new Reader that uses the modified environment\n * const modifiedReader = Reader.local(upgradeApi, reader);\n *\n * // Define an example environment\n * const env: Env = { apiEndpoint: 'https://api.example.com', version: 'v1' };\n *\n * // Run the original Reader with the example environment\n * console.log(reader.run(env)); // 'https://api.example.com'\n *\n * // Run the modified Reader with the example environment\n * console.log(modifiedReader.run(env)); // 'https://api.example.com'\n */\n static local<R, A>(f: (env: R) => R, reader: Reader<R, A>): Reader<R, A> {\n return new Reader((env: R) => reader.run(f(env)));\n }\n\n /**\n * Executes the `Reader` computation with the given environment.\n *\n * This method is used to run the `Reader` and obtain its result by providing\n * the necessary environment. It applies the environment to the encapsulated\n * function and returns the computed value.\n *\n * @param env - The environment to be provided to the `Reader` computation.\n * @returns The result of the `Reader` computation.\n *\n * @example\n * // Define an environment type\n * type Env = { apiEndpoint: string };\n *\n * // Create a Reader that reads the API endpoint from the environment\n * const reader = Reader.ask<Env>().map(env => env.apiEndpoint);\n *\n * // Define an example environment\n * const env: Env = { apiEndpoint: 'https://api.example.com' };\n *\n * // Run the Reader with the example environment\n * console.log(reader.run(env)); // 'https://api.example.com'\n */\n run(env: R): A {\n return this.f(env);\n }\n}\n","/**\n * Represents the result of comparing two values, encapsulating the possible outcomes of an ordering comparison.\n * The `Ordering` class provides a type-safe and expressive way to handle comparison results,\n * offering methods and static properties to facilitate common operations in sorting and comparison logic.\n *\n * **Possible Values of `Ordering`**:\n *\n * - `Ordering.LessThan` (alias `LT`): Indicates that the first value is less than the second.\n * - `Ordering.Equal` (alias `EQ`): Indicates that the first value is equal to the second.\n * - `Ordering.GreaterThan` (alias `GT`): Indicates that the first value is greater than the second.\n *\n * **Key Features**:\n *\n * - **Type Safety**: Encapsulates comparison results, reducing errors associated with using raw numeric values.\n * - **Functional Methods**: Provides methods like `match`, `flatMap`, `concat`, and `reverse` to work with ordering values in a functional style.\n * - **Comparator Utilities**: Includes static methods `from`, `comparing`, and `compareBy` to create and combine comparator functions.\n *\n * **Usage Examples**:\n *\n * **Basic Comparison**:\n *\n * ```typescript\n * const a = 5;\n * const b = 10;\n * const ordering = Ordering.from(a - b);\n *\n * ordering.match(\n * () => console.log('a is less than b'),\n * () => console.log('a is equal to b'),\n * () => console.log('a is greater than b')\n * );\n * // Output: 'a is less than b'\n * ```\n *\n * **Sorting an Array**:\n *\n * ```typescript\n * const numbers = [3, 1, 4, 1, 5];\n * numbers.sort((a, b) => Ordering.from(a - b).value);\n * console.log(numbers);\n * // Output: [1, 1, 3, 4, 5]\n * ```\n *\n * **Using Comparators with Complex Types**:\n *\n * ```typescript\n * interface User {\n * age: number;\n * name: string;\n * }\n *\n * const users: User[] = [\n * { age: 30, name: 'Charlie' },\n * { age: 25, name: 'Alice' },\n * { age: 30, name: 'Bob' },\n * ];\n *\n * const compareByAge = Ordering.comparing<User, number>(\n * (u) => u.age,\n * (a, b) => a - b\n * );\n *\n * const compareByName = Ordering.comparing<User, string>(\n * (u) => u.name,\n * (a, b) => a.localeCompare(b)\n * );\n *\n * const userComparator = Ordering.compareBy(compareByAge, compareByName);\n *\n * users.sort((a, b) => userComparator(a, b).value);\n * console.log(users);\n * // Output:\n * // [\n * // { age: 25, name: 'Alice' },\n * // { age: 30, name: 'Bob' },\n * // { age: 30, name: 'Charlie' }\n * // ]\n * ```\n *\n * **Chaining Comparisons**:\n *\n * ```typescript\n * interface User {\n * name: string;\n * age: number;\n * }\n *\n * const user1: User = { name: 'Alice', age: 30 };\n * const user2: User = { name: 'Alice', age: 25 };\n *\n * const ordering = Ordering.from(user1.name.localeCompare(user2.name)).flatMap(() =>\n * Ordering.from(user1.age - user2.age)\n * );\n *\n * ordering.match(\n * () => console.log('user1 comes before user2'),\n * () => console.log('user1 and user2 are equal'),\n * () => console.log('user1 comes after user2')\n * );\n * // Output: 'user1 comes after user2' (because 30 > 25)\n * ```\n *\n * **Reversing an Ordering**:\n *\n * ```typescript\n * const a = 5;\n * const b = 10;\n * const ordering = Ordering.from(a - b).reverse();\n * console.log(ordering.type); // Output: 'GreaterThan'\n * ```\n *\n * **Design Considerations**:\n *\n * - **Immutability**: The `Ordering` instances are immutable and can be safely reused.\n * - **Singleton Instances**: Uses static instances for `LessThan`, `Equal`, and `GreaterThan` to prevent unnecessary object creation.\n *\n * **Aliases**:\n *\n * - `LT`: Alias for `Ordering.LessThan`\n * - `EQ`: Alias for `Ordering.Equal`\n * - `GT`: Alias for `Ordering.GreaterThan`\n *\n * **Common Use Cases**:\n *\n * - Implementing custom sorting logic for arrays and collections.\n * - Comparing optional values or complex data structures.\n * - Building composite comparators for multi-level sorting criteria.\n *\n * @export\n * @class Ordering\n */\nexport class Ordering {\n private constructor(\n public readonly value: -1 | 0 | 1,\n public readonly type: \"LessThan\" | \"Equal\" | \"GreaterThan\"\n ) {}\n\n /**\n * Indicates that the first value is less than the second.\n * @static\n * @type {Ordering}\n */\n static readonly LessThan: Ordering = new Ordering(-1, \"LessThan\");\n\n /**\n * Indicates that the first value is equal to the second.\n * @static\n * @type {Ordering}\n */\n static readonly Equal: Ordering = new Ordering(0, \"Equal\");\n\n /**\n * Indicates that the first value is greater than the second.\n * @static\n * @type {Ordering}\n */\n static readonly GreaterThan: Ordering = new Ordering(1, \"GreaterThan\");\n\n /**\n * Chains multiple `Ordering` computations, allowing for sequential comparisons based on multiple criteria.\n *\n * - If the current `Ordering` is `Equal`, it invokes the provided function `f` to obtain the next `Ordering`.\n * - If the current `Ordering` is `LessThan` or `GreaterThan`, it returns the current `Ordering` without invoking `f`.\n *\n * This method is useful when you have multiple comparison criteria and want to proceed to the next\n * comparison only if previous ones are equal. It enables the construction of composite comparisons in a functional and readable manner.\n *\n * @param {() => Ordering} f - A function that returns the next `Ordering` to consider if the current `Ordering` is `Equal`.\n * @returns {Ordering} The current `Ordering` if it is `LessThan` or `GreaterThan`; otherwise, the result of invoking `f`.\n *\n * @example\n * // Example: Comparing users by name, then by age if names are equal\n * interface User {\n * name: string;\n * age: number;\n * }\n *\n * const user1: User = { name: 'Alice', age: 30 };\n * const user2: User = { name: 'Alice', age: 25 };\n *\n * const ordering = Ordering.from(user1.name.localeCompare(user2.name)).flatMap(() =>\n * Ordering.from(user1.age - user2.age)\n * );\n *\n * ordering.match(\n * () => console.log('user1 comes before user2'),\n * () => console.log('user1 and user2 are equal'),\n * () => console.log('user1 comes after user2')\n * );\n * // Output: 'user1 comes after user2' (because 30 > 25)\n */\n flatMap(f: () => Ordering): Ordering {\n return this.type === \"Equal\" ? f() : this;\n }\n\n /**\n * Executes one of the provided functions based on the current `Ordering`, effectively performing pattern matching.\n *\n * - If the `Ordering` is `LessThan`, it invokes `onLessThan`.\n * - If the `Ordering` is `Equal`, it invokes `onEqual`.\n * - If the `Ordering` is `GreaterThan`, it invokes `onGreaterThan`.\n *\n * This method allows you to handle each possible outcome of an `Ordering` explicitly, similar to pattern matching in functional programming languages.\n *\n * @template B The return type of the provided functions and the `match` method.\n * @param {() => B} onLessThan - Function to execute if the `Ordering` is `LessThan`.\n * @param {() => B} onEqual - Function to execute if the `Ordering` is `Equal`.\n * @param {() => B} onGreaterThan - Function to execute if the `Ordering` is `GreaterThan`.\n * @returns {B} The result of the function corresponding to the current `Ordering`.\n *\n * @example\n * const a = 5;\n * const b = 10;\n * const ordering = Ordering.from(a - b);\n * const message = ordering.match(\n * () => 'a is less than b',\n * () => 'a is equal to b',\n * () => 'a is greater than b'\n * );\n * console.log(message);\n * // Output: 'a is less than b'\n */\n match<B>(onLessThan: () => B, onEqual: () => B, onGreaterThan: () => B): B {\n switch (this.type) {\n case \"LessThan\":\n return onLessThan();\n case \"Equal\":\n return onEqual();\n case \"GreaterThan\":\n return onGreaterThan();\n }\n }\n\n /**\n * Reverses the current `Ordering`, effectively inverting the comparison result.\n *\n * - `LessThan` becomes `GreaterThan`\n * - `GreaterThan` becomes `LessThan`\n * - `Equal` remains `Equal`\n *\n * This method is useful when you want to invert the sorting order or reverse the result of a comparison.\n *\n * @returns {Ordering} The reversed `Ordering`.\n *\n * @example\n * // Example: Reversing the ordering to sort numbers in descending order\n * const numbers = [1, 2, 3, 4, 5];\n *\n * // Sort in ascending order\n * numbers.sort((a, b) => Ordering.from(a - b).value);\n * console.log(numbers);\n * // Output: [1, 2, 3, 4, 5]\n *\n * // Sort in descending order using reverse()\n * numbers.sort((a, b) => Ordering.from(a - b).reverse().value);\n * console.log(numbers);\n * // Output: [5, 4, 3, 2, 1]\n */\n reverse(): Ordering {\n switch (this.type) {\n case \"LessThan\":\n return Ordering.GreaterThan;\n case \"Equal\":\n return Ordering.Equal;\n case \"GreaterThan\":\n return Ordering.LessThan;\n }\n }\n\n /**\n * Performs a side effect based on the current `Ordering` and returns the `Ordering` unchanged.\n *\n * This method is useful for executing side effects (such as logging, debugging, or updating external state) without interrupting the flow of method chaining. It allows you to observe or react to the current `Ordering` while continuing to work with it in a fluent interface style.\n *\n * @param {(ordering: Ordering) => void} f - A function that takes the current `Ordering` as an argument and performs a side effect.\n * @returns {Ordering} The current `Ordering`, allowing for method chaining.\n *\n * @example\n * // Example: Logging the Ordering during a comparison\n * const a = 5;\n * const b = 10;\n *\n * const ordering = Ordering.from(a - b).tap(o => console.log(`Ordering is: ${o.type}`));\n * // Output: 'Ordering is: LessThan'\n *\n * // Continue using the ordering\n * ordering.match(\n * () => console.log('a is less than b'),\n * () => console.log('a is equal to b'),\n * () => console.log('a is greater than b')\n * );\n * // Output: 'a is less than b'\n */\n tap(f: (ordering: Ordering) => void): Ordering {\n f(this);\n return this;\n }\n\n /**\n * Combines this `Ordering` with another `Ordering`, returning the first non-`Equal` result.\n *\n * - If the current `Ordering` is not `Equal` (`LessThan` or `GreaterThan`), it returns the current `Ordering`.\n * - If the current `Ordering` is `Equal`, it returns the `other` `Ordering`.\n *\n * This method is useful when you have multiple comparison criteria and want to determine the overall `Ordering` by considering each criterion in sequence. It allows you to combine two `Ordering` instances, effectively cascading the comparison to the next criterion if the current one is inconclusive (`Equal`).\n *\n * @param {Ordering} other - The next `Ordering` to consider if the current `Ordering` is `Equal`.\n * @returns {Ordering} The first non-`Equal` `Ordering`; if both are `Equal`, returns `Equal`.\n *\n * @example\n * // Example: Combining orderings to compare strings by length and then alphabetically\n * const compareByLength = (a: string, b: string): Ordering =>\n * Ordering.from(a.length - b.length);\n *\n * const compareAlphabetically = (a: string, b: string): Ordering =>\n * Ordering.from(a.localeCompare(b));\n *\n * const compareStrings = (a: string, b: string): Ordering =>\n * compareByLength(a, b).concat(compareAlphabetically(a, b));\n *\n * const result = compareStrings('apple', 'banana');\n *\n * result.match(\n * () => console.log('\"apple\" comes before \"banana\"'),\n * () => console.log('\"apple\" and \"banana\" are equal'),\n * () => console.log('\"apple\" comes after \"banana\"')\n * );\n * // Output: '\"apple\" comes before \"banana\"' (because 'apple' is shorter than 'banana')\n *\n * @example\n * // Using concat in sorting an array of strings by length, then alphabetically\n * const fruits = ['kiwi', 'apple', 'banana', 'cherry', 'date'];\n *\n * const compareByLength = (a: string, b: string): Ordering =>\n * Ordering.from(a.length - b.length);\n *\n * const compareAlphabetically = (a: string, b: string): Ordering =>\n * Ordering.from(a.localeCompare(b));\n *\n * fruits.sort((a, b) =>\n * compareByLength(a, b).concat(compareAlphabetically(a, b)).value\n * );\n *\n * console.log(fruits);\n * // Output: [ 'date', 'kiwi', 'apple', 'banana', 'cherry' ]\n * // Explanation:\n * // - 'date' has length 4\n * // - 'kiwi' has length 4\n * // - 'date' comes before 'kiwi' alphabetically\n * // - 'apple' has length 5\n * // - 'banana' and 'cherry' have length 6\n * // - 'banana' comes before 'cherry' alphabetically\n * // - They are sorted alphabetically among themselves\n */\n concat(other: Ordering): Ordering {\n return this.type !== \"Equal\" ? this : other;\n }\n\n /**\n * Converts a numeric comparison result into an `Ordering` instance.\n *\n * This static method interprets the sign of a number to determine the corresponding `Ordering`:\n *\n * - **`Ordering.LessThan`**: Returned if `num` is less than zero (`num < 0`).\n * - **`Ordering.Equal`**: Returned if `num` is exactly zero (`num === 0`).\n * - **`Ordering.GreaterThan`**: Returned if `num` is greater than zero (`num > 0`).\n *\n * **Important Note**: The input `num` must be a valid number and not `NaN`. If `num` is `NaN`, the method throws an error to prevent unexpected behavior.\n *\n * **Use Cases**:\n *\n * - Converting the result of numerical comparisons (e.g., `a - b`) into an `Ordering`.\n * - Integrating with APIs or functions that use the `Ordering` type for comparison logic.\n * - Enhancing type safety by avoiding the use of raw numeric comparison results.\n *\n * @static\n * @param {number} num - The number to convert into an `Ordering` (must not be `NaN`).\n * @returns {Ordering} The corresponding `Ordering` based on the sign of `num`.\n * @throws {Error} Throws an error if `num` is `NaN`.\n *\n * @example\n * // Example: Using Ordering.from with numerical comparisons\n * const result1 = Ordering.from(5 - 10); // Returns Ordering.LessThan\n * const result2 = Ordering.from(10 - 5); // Returns Ordering.GreaterThan\n * const result3 = Ordering.from(5 - 5); // Returns Ordering.Equal\n *\n * @example\n * // Example: Handling invalid input (NaN)\n * try {\n * const invalidResult = Ordering.from(NaN);\n * } catch (error) {\n * console.error(error.message); // Output: 'Cannot convert NaN to Ordering.'\n * }\n *\n * @example\n * // Example: Using Ordering.from in a custom comparator function\n * const compareNumbers = (a: number, b: number): Ordering => Ordering.from(a - b);\n *\n * const ordering = compareNumbers(15, 10);\n * console.log(ordering.type); // Output: 'GreaterThan'\n */\n static from(num: number): Ordering {\n if (isNaN(num)) {\n throw new Error(\"Cannot convert NaN to Ordering.\");\n }\n if (num < 0) return Ordering.LessThan;\n if (num > 0) return Ordering.GreaterThan;\n return Ordering.Equal;\n }\n\n /**\n * Creates a comparator function for items of type `A` by comparing their keys of type `B`,\n * which are obtained via a selector function. The comparison of the keys is performed using\n * a provided comparator function for type `B`.\n *\n * This static method is useful for creating comparator functions for complex data structures,\n * where you need to sort or compare items based on a specific property or derived value.\n *\n * **How It Works**:\n *\n * - The `selector` function extracts a key of type `B` from an item of type `A`.\n * - The `comparator` function compares two keys of type `B` and returns a numeric result.\n * - The returned comparator function takes two items of type `A`, extracts their keys using the `selector`,\n * compares the keys using the `comparator`, and converts the numeric result into an `Ordering` using `Ordering.from`.\n *\n * **Important Note**:\n *\n * - The `comparator` function should return a valid number (not `NaN`). If the result is `NaN`, an error is thrown.\n *\n * **Type Parameters**:\n *\n * - `A`: The type of the items to compare.\n * - `B`: The type of the keys extracted from the items.\n *\n * @static\n * @template A The type of the items to compare.\n * @template B The type of the keys to compare.\n * @param {(item: A) => B} selector - A function that selects the comparison key from an item of type `A`.\n * @param {(a: B, b: B) => number} comparator - A comparator function for keys of type `B` (should return a valid number, not `NaN`).\n * @returns {(a: A, b: A) => Ordering} A comparator function that takes two items of type `A` and returns an `Ordering`.\n * @throws {Error} Throws an error if the `comparator` function returns `NaN`.\n *\n * @example\n * // Example: Comparing users by age\n * interface User {\n * name: string;\n * age: number;\n * }\n *\n * const users: User[] = [\n * { name: 'Alice', age: 30 },\n * { name: 'Bob', age: 25 },\n * { name: 'Charlie', age: 35 },\n * ];\n *\n * const compareByAge = Ordering.comparing<User, number>(\n * user => user.age, // Selector function to extract the age\n * (a, b) => a - b // Comparator function for numbers\n * );\n *\n * // Using the comparator to sort the array\n * users.sort((a, b) => compareByAge(a, b).value);\n *\n * console.log(users);\n * // Output:\n * // [\n * // { name: 'Bob', age: 25 },\n * // { name: 'Alice', age: 30 },\n * // { name: 'Charlie', age: 35 },\n * // ]\n *\n * @example\n * // Example: Comparing strings by length\n * const strings = ['apple', 'banana', 'cherry', 'date'];\n *\n * const compareByLength = Ordering.comparing<string, number>(\n * str => str.length, // Selector function to get the length\n * (a, b) => a - b // Comparator function for numbers\n * );\n *\n * strings.sort((a, b) => compareByLength(a, b).value);\n *\n * console.log(strings);\n * // Output: ['date', 'apple', 'banana', 'cherry']\n *\n * @example\n * // Example: Comparing products by price, handling potential NaN values\n * interface Product {\n * name: string;\n * price: number;\n * }\n *\n * const products: Product[] = [\n * { name: 'Product A', price: 10 },\n * { name: 'Product B', price: NaN }, // Invalid price\n * { name: 'Product C', price: 5 },\n * ];\n *\n * const compareByPrice = Ordering.comparing<Product, number>(\n * product => product.price,\n * (a, b) => a - b\n * );\n *\n * try {\n * products.sort((a, b) => compareByPrice(a, b).value);\n * } catch (error) {\n * console.error(error.message); // Output: 'Comparator function returned NaN.'\n * }\n */\n static comparing<A, B>(selector: (item: A) => B, comparator: (a: B, b: B) => number): (a: A, b: A) => Ordering {\n return (a: A, b: A) => {\n const result = comparator(selector(a), selector(b));\n if (isNaN(result)) {\n throw new Error(\"Comparator function returned NaN.\");\n }\n return Ordering.from(result);\n };\n }\n\n /**\n * Creates a composite comparator function by combining multiple comparator functions.\n *\n * This static method allows you to chain multiple comparator functions, applying them sequentially to compare two items of type `A`. It returns the result of the first comparator that does not return `Equal`. If all comparators return `Equal`, the combined comparator returns `Equal`.\n *\n * **How It Works**:\n *\n * - The method accepts a variable number of comparator functions (`comparators`), each of which compares two items of type `A` and returns an `Ordering`.\n * - The returned comparator function takes two items `a` and `b`, and applies each comparator in the provided order.\n * - For each comparator, if the result is not `Equal`, it returns that `Ordering` immediately.\n * - If all comparators return `Equal`, it returns `Ordering.Equal`.\n *\n * **Use Cases**:\n *\n * - Useful when you need to compare items based on multiple criteria, proceeding to the next criterion only if previous comparisons are inconclusive (`Equal`).\n * - Helps in building complex sorting logic in a clean and readable manner.\n *\n * **Type Parameters**:\n *\n * - `A`: The type of the items to compare.\n *\n * @static\n * @template A The type of the items to compare.\n * @param {...Array<(a: A, b: A) => Ordering>} comparators - A variable number of comparator functions to be combined.\n * @returns {(a: A, b: A) => Ordering} A composite comparator function that applies each comparator in order.\n *\n * @example\n * // Example: Comparing users by last name, then first name\n * interface User {\n * firstName: string;\n * lastName: string;\n * age: number;\n * }\n *\n * const users: User[] = [\n * { firstName: 'John', lastName: 'Doe', age: 30 },\n * { firstName: 'Jane', lastName: 'Doe', age: 25 },\n * { firstName: 'Alice', lastName: 'Smith', age: 28 },\n * { firstName: 'Bob', lastName: 'Brown', age: 35 },\n * ];\n *\n * const compareByLastName = Ordering.comparing<User, string>(\n * user => user.lastName,\n * (a, b) => a.localeCompare(b)\n * );\n *\n * const compareByFirstName = Ordering.comparing<User, string>(\n * user => user.firstName,\n * (a, b) => a.localeCompare(b)\n * );\n *\n * const userComparator = Ordering.compareBy<User>(\n * compareByLastName,\n * compareByFirstName\n * );\n *\n * // Using the comparator to sort the array\n * users.sort((a, b) => userComparator(a, b).value);\n *\n * console.log(users);\n * // Output:\n * // [\n * // { firstName: 'Bob', lastName: 'Brown', age: 35 },\n * // { firstName: 'Jane', lastName: 'Doe', age: 25 },\n * // { firstName: 'John', lastName: 'Doe', age: 30 },\n * // { firstName: 'Alice', lastName: 'Smith', age: 28 },\n * // ]\n *\n * @example\n * // Example: Comparing products by category, then price\n * interface Product {\n * name: string;\n * category: string;\n * price: number;\n * }\n *\n * const products: Product[] = [\n * { name: 'Product A', category: 'Electronics', price: 99 },\n * { name: 'Product B', category: 'Clothing', price: 49 },\n * { name: 'Product C', category: 'Electronics', price: 199 },\n * { name: 'Product D', category: 'Clothing', price: 29 },\n * ];\n *\n * const compareByCategory = Ordering.comparing<Product, string>(\n * product => product.category,\n * (a, b) => a.localeCompare(b)\n * );\n *\n * const compareByPrice = Ordering.comparing<Product, number>(\n * product => product.price,\n * (a, b) => a - b\n * );\n *\n * const productComparator = Ordering.compareBy<Product>(\n * compareByCategory,\n * compareByPrice\n * );\n *\n * // Using the comparator to sort the array\n * products.sort((a, b) => productComparator(a, b).value);\n *\n * console.log(products);\n * // Output:\n * // [\n * // { name: 'Product D', category: 'Clothing', price: 29 },\n * // { name: 'Product B', category: 'Clothing', price: 49 },\n * // { name: 'Product A', category: 'Electronics', price: 99 },\n * // { name: 'Product C', category: 'Electronics', price: 199 },\n * // ]\n *\n * @example\n * // Example: Using compareBy with different types of comparators\n * const compareByLength = Ordering.comparing<string, number>(\n * str => str.length,\n * (a, b) => a - b\n * );\n *\n * const compareAlphabetically = Ordering.comparing<string, string>(\n * str => str,\n * (a, b) => a.localeCompare(b)\n * );\n *\n * const stringComparator = Ordering.compareBy<string>(\n * compareByLength,\n * compareAlphabetically\n * );\n *\n * const strings = ['apple', 'banana', 'cherry', 'date', 'fig'];\n *\n * strings.sort((a, b) => stringComparator(a, b).value);\n *\n * console.log(strings);\n * // Output: ['fig', 'date', 'apple', 'banana', 'cherry']\n *\n * // Explanation:\n * // - 'fig' has length 3\n * // - 'date' has length 4\n * // - 'apple', 'banana', and 'cherry' have length 5, sorted alphabetically\n */\n static compareBy<A>(...comparators: Array<(a: A, b: A) => Ordering>): (a: A, b: A) => Ordering {\n return (a: A, b: A) => {\n for (const comparator of comparators) {\n const result = comparator(a, b);\n if (result.type !== \"Equal\") {\n return result;\n }\n }\n return Ordering.Equal;\n };\n }\n}\n\n/**\n * Alias for `Ordering.LessThan`.\n *\n * Represents the `Ordering` where the first value is less than the second.\n *\n * @example\n * if (ordering === LT) {\n * console.log('First value is less than the second.');\n * }\n *\n * @see Ordering.LessThan\n */\nexport const LT = Ordering.LessThan;\n\n/**\n * Alias for `Ordering.Equal`.\n *\n * Represents the `Ordering` where the first value is equal to the second.\n *\n * @example\n * if (ordering === EQ) {\n * console.log('Values are equal.');\n * }\n *\n * @see Ordering.Equal\n */\nexport const EQ = Ordering.Equal;\n\n/**\n * Alias for `Ordering.GreaterThan`.\n *\n * Represents the `Ordering` where the first value is greater than the second.\n *\n * @example\n * if (ordering === GT) {\n * console.log('First value is greater than the second.');\n * }\n *\n * @see Ordering.GreaterThan\n */\nexport const GT = Ordering.GreaterThan;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"monadyssey.cjs","names":[],"sources":["../src/either.ts","../src/utils.ts","../src/option.ts","../src/non-empty-list.ts","../src/list.ts","../src/schedule.ts","../src/io.ts","../src/eval.ts","../src/reader.ts","../src/ordering.ts"],"sourcesContent":["/**\n * Represents a type which is either a Left (failure) or a Right (success).\n * Left typically stores an error or failure state, while Right stores a success value.\n */\nexport abstract class Either<A, B> {\n abstract readonly type: \"Left\" | \"Right\";\n\n /**\n * Property to access the actual `Either` instance, enabling exhaustive type checking and type narrowing.\n * Use this when a switch statement needs to handle each subtype distinctly.\n *\n * @example\n * function isAlive(cat: Either<\"dead\", \"alive\">): boolean {\n * // switch is exhaustive without a default branch\n * switch (cat.self.value) {\n * case \"dead\":\n * return false;\n * case \"alive\":\n * return true;\n * }\n * }\n */\n abstract readonly self: Left<A> | Right<B>;\n\n /**\n * Catch function with automatic conversion to Either<string, B>.\n * This version is used when no transformation function is provided.\n * It captures exceptions, converts them to a string, and wraps them in a Left.\n * If the operation is successful, the result is wrapped in a Right.\n *\n * @param fn - A function that might throw an error.\n * @returns {Either<string, B>} - Either an error message as a string or the successful result.\n *\n * @example\n * function gambleWithFailure() {\n * if (Math.random() > 0.5) {\n * throw \"Something went wrong\";\n * }\n * return \"Success\";\n * }\n *\n * const result = Either.catch(gambleWithFailure); // Left<string>(\"Something went wrong\") | Right<string>(\"Success\")\n */\n static catch<B>(fn: () => B): Either<string, B>;\n\n /**\n * Catch function with a custom transformation from unknown to A.\n * This version provides maximum flexibility, allowing any type of caught error to be transformed into type A.\n *\n * @param fn - A function that might throw an error.\n * @param liftE - A function that takes an unknown error and returns type A.\n * @returns {Either<A, B>} - Either the transformed error or the successful result.\n *\n * @example\n * function gambleWithFailure() {\n * if (Math.random() > 0.5) {\n * throw \"Something went wrong\";\n * }\n * return \"Success\";\n * }\n *\n * type MyError =\n * | \"GAMBLE_FAILED\"\n * | \"UNKNOWN_FAILURE\"\n *\n * const result2 = Either.catch(gambleWithFailure, (e: unknown): MyError => {\n * if (typeof e === \"string\") {\n * return \"GAMBLE_FAILED\";\n * } else {\n * return \"UNKNOWN_FAILURE\";\n * }\n * });\n */\n static catch<A, B>(fn: () => B, liftE: (e: unknown) => A): Either<A, B>;\n\n static catch<A, B>(fn: () => B, liftE?: (e: unknown) => A): Left<string> | Left<A> | Right<B> {\n try {\n return Right.pure(fn());\n } catch (e: unknown) {\n if (liftE) {\n return Left.pure(liftE(e));\n }\n\n const defaultLiftE = (e: unknown): string => {\n if (typeof e === \"string\") {\n return e;\n } else if (e && typeof (e as any).message === \"string\") {\n return (e as { message: string }).message;\n } else {\n return String(e);\n }\n };\n return Left.pure(defaultLiftE(e));\n }\n }\n\n /**\n * Transforms the right value of this Either by applying a function and returns a new Either.\n * @param f - A transformation function to apply to the right value.\n * @returns A new Either instance with the transformed value if this is a Right; otherwise, a Left.\n * @example\n * const result = Right.pure(5).map(x => x * 2); // Returns Right(10)\n */\n abstract map<C>(f: (right: B) => C): Either<A, C>;\n\n /**\n * Transforms the left value of this Either by applying a function and returns a new Either.\n * @param f - A transformation function to apply to the left value.\n * @returns A new Either instance with the transformed value if this is a Left; otherwise, a Right.\n * @example\n * const result = Left.pure(5).mapLeft(x => x * 2); // Returns Left(10)\n */\n abstract mapLeft<C>(f: (left: A) => C): Either<C, B>;\n\n /**\n * Applies a transformation function to the right value that returns an Either,\n * enabling chaining of operations that may fail.\n * @param f - A transformation function to apply that returns an Either.\n * @returns The result of the function if this is a Right; otherwise, a Left.\n * @example\n * const result = Right.pure(5).flatMap(x => Right.pure(x * 2)); // Returns Right(10)\n */\n abstract flatMap<C>(f: (right: B) => Either<A, C>): Either<A, C>;\n\n /**\n * Returns the value from this `Right` or the given argument if this is a `Left`.\n * @param value - A function that returns the default value.\n * @returns The value of `Right` or the result of `value`.\n * @example\n * Right.pure(5).getOrElse(() => 0); // Returns 5\n * Left.pure(\"error\").getOrElse(() => 0); // Returns 0\n */\n abstract getOrElse(value: (left: A) => B): B;\n\n /**\n * Returns the value from this `Right` or `null` if this is a `Left`.\n * @returns The value of `Right` or `null`.\n */\n abstract getOrNull(): B | null;\n\n /**\n * Swaps the `Left` and `Right` types.\n * @returns A new `Either` with the types swapped.\n */\n abstract swap(): Either<B, A>;\n\n /**\n * Applies one of two provided functions based on the contents of this Either.\n * @param ifLeft - A function to handle a Left value.\n * @param ifRight - A function to handle a Right value.\n * @returns The result of the applied function.\n * @example\n * const result = Right.pure(5).fold(\n * error => 'Error occurred',\n * value => 'Success with ' + value\n * ); // Returns 'Success with 5'\n */\n abstract fold<C>(ifLeft: (left: A) => C, ifRight: (right: B) => C): C;\n\n /**\n * Executes a provided function if this is a Right, used for side effects.\n * @param action - A function to execute with the right value.\n * @returns The original Either instance, facilitating method chaining.\n * @example\n * Right.pure(5).onRight(value => console.log(value)); // Logs \"5\"\n */\n abstract tap(action: (right: B) => void): Either<A, B>;\n\n /**\n * Executes a provided function if this is a Left, used for side effects.\n * @param action - A function to execute with the left value.\n * @returns The original Either instance, facilitating method chaining.\n * @example\n * Left.pure('Error').onLeft(err => console.log(err)); // Logs \"Error\"\n */\n abstract tapLeft(action: (left: A) => void): Either<A, B>;\n}\n\nexport class Left<A> extends Either<A, never> {\n readonly type = \"Left\" as const;\n\n readonly self: Left<A> = this;\n\n private constructor(public readonly value: A) {\n super();\n }\n\n static pure<A>(value: A): Left<A> {\n return new Left<A>(value);\n }\n\n map<C>(_: (right: never) => C): Either<A, C> {\n return this;\n }\n\n mapLeft<C>(f: (left: A) => C): Either<C, never> {\n return new Left(f(this.value));\n }\n\n flatMap<C>(_: (right: never) => Either<A, C>): Either<A, C> {\n return this;\n }\n\n getOrElse(defaultValue: (left: A) => never): never {\n return defaultValue(this.value);\n }\n\n getOrNull(): null {\n return null;\n }\n\n swap(): Either<never, A> {\n return Right.pure(this.value);\n }\n\n fold<C>(ifLeft: (left: A) => C, _: (right: never) => C): C {\n return ifLeft(this.value);\n }\n\n tap(_: (right: never) => void): Either<A, never> {\n return this;\n }\n\n tapLeft(action: (left: A) => void): Either<A, never> {\n action(this.value);\n return this;\n }\n}\n\nexport class Right<B> extends Either<never, B> {\n readonly type = \"Right\" as const;\n\n readonly self: Right<B> = this;\n\n private constructor(public readonly value: B) {\n super();\n }\n\n static pure<B>(value: B): Right<B> {\n return new Right<B>(value);\n }\n\n map<C>(f: (right: B) => C): Either<never, C> {\n return new Right<C>(f(this.value));\n }\n\n mapLeft<C>(_: (left: never) => C): Either<C, B> {\n return this;\n }\n\n flatMap<A, C>(f: (right: B) => Either<A, C>): Either<A, C> {\n return f(this.value);\n }\n\n getOrElse(_: (left: never) => B): B {\n return this.value;\n }\n\n getOrNull(): B {\n return this.value;\n }\n\n swap(): Either<B, never> {\n return Left.pure(this.value);\n }\n\n fold<C>(_: (left: never) => C, ifRight: (right: B) => C): C {\n return ifRight(this.value);\n }\n\n tap(action: (right: B) => void): Either<never, B> {\n action(this.value);\n return this;\n }\n\n tapLeft(_: (left: never) => void): Either<never, B> {\n return this;\n }\n}\n","/**\n * Throws a NotImplementedYet error indicating that a feature or functionality is not yet implemented.\n * This function is typically used as a placeholder for incomplete functionality.\n *\n * @throws {NotImplementedYetError} Throws a NotImplementedYet error with a message \"Not implemented yet\".\n * @returns {never} This function never returns as it always throws an error.\n *\n * @example\n * function someFunction() {\n * TODO();\n * }\n */\nexport function TODO(): never {\n throw new NotImplementedYetError(\"Not implemented yet\");\n}\n\n/**\n * Returns the input value without any modification. This function serves as an identity function,\n * returning the same value that is passed to it.\n *\n * @template A The type of the input value.\n * @param {A} a The input value.\n * @returns {A} The same value that was passed as input.\n *\n * @example\n * // Returns 5\n * identity(5);\n *\n * // Returns \"Hello\"\n * identity(\"Hello\");\n *\n * // Returns { x: 10, y: 20 }\n * identity({ x: 10, y: 20 });\n */\nexport function identity<A>(a: A): A {\n return a;\n}\n\n/**\n * Represents an error indicating that a feature or functionality is not yet implemented.\n * This error is typically thrown to indicate that a particular functionality is still pending development.\n *\n * @extends Error\n * @param {string} message The error message.\n * @property {string} name The name of the error, set to \"NotImplementedYetError\".\n *\n * @example\n * throw new NotImplementedYetError(\"Functionality not yet implemented.\");\n */\nexport class NotImplementedYetError extends Error {\n /**\n * Constructs a new NotImplementedYetError error with the provided message.\n * @param {string} message The error message.\n */\n constructor(message: string) {\n super(message);\n this.name = \"NotImplementedYetError\";\n }\n}\n","import { identity } from \"./utils\";\n\n/**\n * Represents an optional value. Every `Option<A>` is either `Some<A>` containing a value or `None` representing absence of value.\n * This interface supports operations like map, flatMap, and facilitates exhaustive type-checking through type narrowing.\n * @typeParam A - The type of the element contained within a `Some`.\n */\nexport abstract class Option<A> {\n abstract type: \"Some\" | \"None\";\n\n /**\n * Creates an Option instance from a value that may be null or undefined.\n * If the value is null or undefined, Option.None is returned.\n * Otherwise, Option.Some is returned with the given value.\n *\n * @template A The type of the value used to create an Option instance.\n * @param {A | null | undefined} value - The value to create the Option instance from.\n * @returns {Option<A>} - The created Option instance.\n * @example\n * const maybeNumber = Option.ofNullable(5); // Returns Some(5)\n * const maybeNull = Option.ofNullable(null); // Returns None\n */\n static ofNullable<A>(value: A | null | undefined): Option<NonNullable<A>> {\n return value === null || value === undefined ? None.Instance : Some.pure(value as NonNullable<A>);\n }\n\n /**\n * Lifts a non-null, non-undefined value into a `Some`. The companion to `Some.pure`, exposed on\n * the abstract class so users don't need to choose between `Some.pure` and `Option.ofNullable`\n * when they already know the value is present.\n *\n * For values that may be null or undefined, use {@link Option.ofNullable} instead.\n *\n * @template A The type of the value to lift.\n * @param {NonNullable<A>} value The value to wrap.\n * @returns {Option<NonNullable<A>>} `Some(value)`.\n *\n * @example\n * const opt = Option.pure(42); // Some(42)\n */\n static pure<A>(value: NonNullable<A>): Option<NonNullable<A>> {\n return Some.pure(value);\n }\n\n /**\n * Property to access the actual `Option` instance, enabling exhaustive type checking and type narrowing.\n * Use this when a switch statement needs to handle each subtype distinctly.\n *\n * @example\n * function getLength(text: Option<string>): number {\n * switch (text.self.type) {\n * case \"Some\":\n * // Type narrowing allows direct access to the `value`.\n * return text.self.value.length;\n * case \"None\":\n * return 0;\n * }\n * }\n */\n abstract self: None | Some<A>;\n\n /**\n * Transforms the `Option`'s value using a provided function, returning a new `Option` with the result.\n * If the `Option` is `None`, it returns `None`.\n * @example\n * const numberOption = Option.Some(5);\n * const incrementedOption = numberOption.map(x => x + 1); // Returns Some(6)\n */\n map<B>(f: (value: A) => B): Option<B> {\n return this.flatMap((value) => {\n const result = f(value);\n return result === null || result === undefined ? None.Instance : Some.pure(result as NonNullable<B>);\n });\n }\n\n /**\n * Applies a function that returns an `Option` to the `Option`'s value, if it exists, and flattens the result.\n * If the `Option` is `None`, it returns `None`.\n * @example\n * const numberOption = Option.Some(5);\n * const nestedOption = numberOption.flatMap(x => Option.Some(x + 1)); // Returns Some(6)\n */\n abstract flatMap<B>(f: (value: A) => Option<B>): Option<B>;\n\n /**\n * Returns this `Option` if it is a `Some` and the predicate returns `true`, otherwise returns `None`.\n * @param predicate - The predicate to test the value against.\n * @example\n * Option.Some(5).filter(x => x > 0); // Returns Some(5)\n * Option.Some(-5).filter(x => x > 0); // Returns None\n */\n abstract filter(predicate: (value: A) => boolean): Option<A>;\n\n /**\n * Executes a provided function if this `Option` is a `Some`, typically used for side effects.\n * Returns the original `Option` instance to facilitate method chaining.\n * @example\n * Option.Some(5).tap(value => console.log(value)); // Logs \"5\"\n * Option.None.tap(value => console.log(value)); // Does nothing\n */\n abstract tap(f: (value: A) => void): Option<A>;\n\n /**\n * Executes a provided function if this `Option` is a `None`, typically used for side effects.\n * Returns the original `Option` instance to facilitate method chaining.\n * @example\n * Option.Some(5).tapNone(() => console.log(\"No value\")); // Does nothing\n * Option.None.tapNone(() => console.log(\"No value\")); // Logs \"No value\"\n */\n abstract tapNone(f: () => void): Option<A>;\n\n /**\n * Applies one of two provided functions based on the contents of this `Option`.\n * If it is `None`, it applies `ifNone`. If it is `Some`, it applies `ifSome`.\n * @returns The result of the applied function.\n * @example\n * const result = Option.Some(5).fold(\n * () => 'No value',\n * value => 'Value is ' + value\n * ); // Returns 'Value is 5'\n */\n abstract fold<B>(ifNone: () => B, ifSome: (value: A) => B): B;\n\n /**\n * Returns the contained value if `Some`, otherwise returns `null`.\n * @example\n * const value = Option.Some(5).getOrNull(); // Returns 5\n * const empty = Option.None.getOrNull(); // Returns null\n */\n getOrNull(): A | null {\n return this.fold(() => null, identity);\n }\n\n /**\n * Returns the contained value if `Some`, otherwise returns the provided default value.\n * @example\n * const value = Option.Some(5).getOrElse(() => 10); // Returns 5\n * const empty = Option.None.getOrElse(() => 10); // Returns 10\n */\n getOrElse(defaultValue: () => A): A {\n return this.fold(() => defaultValue(), identity);\n }\n}\n\n/**\n * Represents an Option that contains no value.\n */\nexport class None extends Option<never> {\n readonly type = \"None\" as const;\n readonly self = this;\n private static readonly instance: None = new None();\n\n private constructor() {\n super();\n }\n\n /**\n * Returns the singleton instance of `None`.\n * @example\n * const emptyOption = None.Instance;\n */\n static get Instance() {\n return None.instance;\n }\n\n flatMap<B>(_: (value: never) => Option<B>): Option<B> {\n return this;\n }\n\n filter(_: (value: never) => boolean): Option<never> {\n return this;\n }\n\n fold<B>(ifNone: () => B, _: (right: never) => B): B {\n return ifNone();\n }\n\n getOrElse(defaultValue: () => never): never {\n return defaultValue();\n }\n\n getOrNull(): null {\n return null;\n }\n\n tap(_: (value: never) => void): Option<never> {\n return this;\n }\n\n tapNone(f: () => void): Option<never> {\n f();\n return this;\n }\n}\n\n/**\n * Represents an Option carrying a value.\n */\nexport class Some<A> extends Option<NonNullable<A>> {\n readonly type = \"Some\" as const;\n readonly self = this;\n\n private constructor(public readonly value: NonNullable<A>) {\n super();\n }\n\n /**\n * Creates a new `Some` instance containing the given value.\n * @param value - The value to wrap.\n * @returns A `Some` instance containing the value.\n * @example\n * const someOption = Some.pure(10);\n */\n static pure<A>(value: NonNullable<A>): Some<NonNullable<A>> {\n return new Some<NonNullable<A>>(value);\n }\n\n flatMap<B>(f: (value: NonNullable<A>) => Option<B>): Option<B> {\n return f(this.value);\n }\n\n filter(predicate: (value: NonNullable<A>) => boolean): Option<NonNullable<A>> {\n return predicate(this.value) ? this : None.Instance;\n }\n\n fold<B>(_: () => B, ifSome: (right: NonNullable<A>) => B): B {\n return ifSome(this.value);\n }\n\n getOrElse(_: () => NonNullable<A>): NonNullable<A> {\n return this.value;\n }\n\n getOrNull(): NonNullable<A> {\n return this.value;\n }\n\n tap(f: (value: NonNullable<A>) => void): Option<NonNullable<A>> {\n f(this.value);\n return this;\n }\n\n tapNone(_: () => void): Option<NonNullable<A>> {\n return this;\n }\n}\n","import { Either, Left, Right } from \"./either\";\nimport { IO } from \"./io\";\nimport { List } from \"./list\";\nimport { None, Option, Some } from \"./option\";\nimport { Ordering } from \"./ordering\";\n\nexport type Nel<A> = NonEmptyList<A>;\n\n/**\n * A list guaranteed to contain at least one element, paired with FP-style operations.\n *\n * `NonEmptyList<A>` is the refinement of {@link List} that statically guarantees a `head`.\n * Operations that preserve or guarantee non-emptiness (`map`, `flatMap`, `append`, `prepend`,\n * `concat`, `reverse`, `sort`, `distinct`, `intersperse`, `zipWithIndex`, `groupBy`, `chunk`,\n * and all `traverseX`) return `NonEmptyList`. Operations that may remove all elements\n * (`filter`, `filterNot`, `collect`, `partition`, `take`, `drop`, `takeWhile`, `dropWhile`,\n * `slice`) return `List<A>`.\n *\n * @template A The type of elements in the list.\n */\nexport class NonEmptyList<A> {\n /**\n * Constructs a new instance of `NonEmptyList` from a head and a tail list.\n * The head ensures the list is non-empty; the tail may be empty.\n *\n * @param {A} head The first element of the list.\n * @param {List<A>} tail The remaining elements, which may be empty.\n */\n constructor(\n public readonly head: A,\n public readonly tail: List<A>\n ) {}\n\n /**\n * Creates a `NonEmptyList` containing a single element.\n *\n * @template A The type of the element.\n * @param {A} value The single element.\n * @returns {NonEmptyList<A>} A `NonEmptyList` with one element and an empty tail.\n *\n * @example\n * const list = NonEmptyList.pure(42);\n * list.head; // 42\n * list.toArray(); // [42]\n * list.size; // 1\n */\n public static pure<A>(value: A): NonEmptyList<A> {\n return new NonEmptyList(value, List.empty<A>());\n }\n\n /**\n * Creates a `NonEmptyList` from an array. Returns `None` when the input is empty (or\n * null/undefined). Mirrors `list.toNel()` in the inverse direction.\n *\n * For statically-known non-empty input, prefer {@link NonEmptyList.of} which is total:\n * `NonEmptyList.of(1, 2, 3)`.\n *\n * @template A The type of elements in the list.\n * @param {readonly A[] | null | undefined} value The source array.\n * @returns {Option<NonEmptyList<A>>} `Some(nel)` if the array has at least one element,\n * `None` otherwise.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]); // Some(NonEmptyList [1, 2, 3])\n * NonEmptyList.fromArray([]); // None\n * NonEmptyList.fromArray(null); // None\n */\n public static fromArray<A>(value: readonly A[] | null | undefined): Option<NonEmptyList<A>> {\n if (!value || value.length === 0) return None.Instance as Option<NonEmptyList<A>>;\n return Some.pure(\n new NonEmptyList<A>(value[0], List._unsafeFromArray(value.slice(1))) as NonNullable<NonEmptyList<A>>\n ) as Option<NonEmptyList<A>>;\n }\n\n /**\n * Constructs a `NonEmptyList` from an array without the `Option` wrapper. The caller must\n * guarantee the array is non-empty; passing an empty array yields a malformed list that\n * will misbehave on access.\n *\n * Used internally by `IO`'s parallel combinators where non-emptiness is structurally\n * guaranteed (errors are collected only when at least one occurred). External code should\n * use {@link NonEmptyList.fromArray} (safe) or {@link NonEmptyList.of} (total) instead.\n *\n * @internal\n */\n public static _unsafeFromArray<A>(value: readonly A[]): NonEmptyList<A> {\n return new NonEmptyList<A>(value[0], List._unsafeFromArray(value.slice(1)));\n }\n\n /**\n * Builds a `NonEmptyList` from an explicit head and a variadic tail. The head argument\n * guarantees non-emptiness at the call site, so no runtime check is needed.\n *\n * @template A The type of elements.\n * @param {A} head The first element.\n * @param {...A[]} tail Additional elements.\n * @returns {NonEmptyList<A>} A new `NonEmptyList`.\n *\n * @example\n * NonEmptyList.of(1, 2, 3).toArray(); // [1, 2, 3]\n * NonEmptyList.of(\"hi\").toArray(); // [\"hi\"]\n */\n public static of<A>(head: A, ...tail: A[]): NonEmptyList<A> {\n return new NonEmptyList<A>(head, List._unsafeFromArray(tail));\n }\n\n /**\n * Returns the total number of elements in the `NonEmptyList`. Always `>= 1`.\n *\n * @returns {number} The total number of elements.\n */\n public get size(): number {\n return 1 + this.tail.size;\n }\n\n /**\n * Returns the last element of the `NonEmptyList`. Always total — never throws.\n *\n * @returns {A} The last element.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).last; // 3\n * NonEmptyList.pure(42).last; // 42\n */\n public get last(): A {\n return this.tail.isEmpty ? this.head : (this.tail.last as Some<A>).value;\n }\n\n /**\n * Returns all elements except the last as a {@link List}.\n * For a single-element list, returns the empty `List`.\n *\n * @returns {List<A>} A `List` of all elements except the last.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).init.toArray(); // [1, 2]\n * NonEmptyList.pure(1).init.toArray(); // []\n */\n public get init(): List<A> {\n if (this.tail.isEmpty) return List.empty();\n return List._unsafeFromArray([this.head, ...this.tail.toArray().slice(0, -1)]);\n }\n\n /**\n * Splits the `NonEmptyList` into its head and tail. Total — always returns a pair.\n *\n * @returns {[A, List<A>]} A tuple of `[head, tail]`.\n *\n * @example\n * const [h, t] = NonEmptyList.fromArray([1, 2, 3]).uncons;\n * h; // 1\n * t.toArray(); // [2, 3]\n */\n public get uncons(): [A, List<A>] {\n return [this.head, this.tail];\n }\n\n /**\n * Returns all elements as a plain array. The returned array is a fresh copy; later\n * mutations do not affect the `NonEmptyList`.\n *\n * @returns {A[]} An array containing all elements, starting with the head.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).toArray(); // [1, 2, 3]\n */\n public toArray(): A[] {\n return [this.head, ...this.tail.toArray()];\n }\n\n /**\n * Widens the `NonEmptyList` to a {@link List}. The returned `List` always has at least one\n * element, but the type system no longer tracks that guarantee.\n *\n * @returns {List<A>} A `List` view of the same elements.\n *\n * @example\n * const list = NonEmptyList.fromArray([1, 2, 3]).toList();\n * list.toArray(); // [1, 2, 3]\n */\n public toList(): List<A> {\n return List._unsafeFromArray(this.toArray());\n }\n\n /**\n * Retrieves the element at a specific zero-based index, where `0` corresponds to the head.\n * Out-of-bounds indices return `None`, matching {@link List.get}.\n *\n * @param {number} i The zero-based index of the element to retrieve.\n * @returns {Option<A>} `Some(element)` if in bounds, `None` otherwise.\n *\n * @example\n * NonEmptyList.fromArray([10, 20, 30]).get(0); // Some(10)\n * NonEmptyList.fromArray([10, 20, 30]).get(2); // Some(30)\n * NonEmptyList.fromArray([10, 20, 30]).get(99); // None\n * NonEmptyList.fromArray([10, 20, 30]).get(-1); // None\n */\n public get(i: number): Option<A> {\n if (i < 0 || i >= this.size) return None.Instance as Option<A>;\n if (i === 0) return Some.pure(this.head as NonNullable<A>) as Option<A>;\n return this.tail.get(i - 1);\n }\n\n /**\n * Applies a function to each element, producing a new `NonEmptyList` of the same length.\n *\n * @template B The type of elements in the resulting list.\n * @param {(value: A) => B} f A function applied to each element.\n * @returns {NonEmptyList<B>} A new `NonEmptyList` with the transformed elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).map(n => n * 2);\n * // NonEmptyList [2, 4, 6]\n */\n public map<B>(f: (value: A) => B): NonEmptyList<B> {\n return new NonEmptyList(f(this.head), this.tail.map(f));\n }\n\n /**\n * Applies a function that returns a `NonEmptyList` to each element, then flattens the\n * results. Because both the receiver and each result are non-empty, the result is too.\n *\n * @template B The type of elements in the resulting list.\n * @param {(value: A) => NonEmptyList<B>} f A function that maps each element to a `NonEmptyList`.\n * @returns {NonEmptyList<B>} A flattened `NonEmptyList` of the results.\n *\n * @example\n * NonEmptyList.fromArray([1, 2]).flatMap(n => NonEmptyList.of(n, n * 10));\n * // NonEmptyList [1, 10, 2, 20]\n */\n public flatMap<B>(f: (value: A) => NonEmptyList<B>): NonEmptyList<B> {\n const headResult = f(this.head);\n const tailArr: B[] = [];\n for (const x of this.tail.toArray()) {\n const sub = f(x);\n tailArr.push(sub.head, ...sub.tail.toArray());\n }\n return new NonEmptyList(headResult.head, List._unsafeFromArray([...headResult.tail.toArray(), ...tailArr]));\n }\n\n /**\n * Reduces the elements from left to right using an accumulator.\n *\n * @template B The type of the accumulator/result.\n * @param {B} start The initial accumulator value.\n * @param {(accumulator: B, value: A) => B} f A function that combines the accumulator with each element.\n * @returns {B} The final accumulated result.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).foldLeft(0, (acc, n) => acc + n); // 6\n */\n public foldLeft<B>(start: B, f: (accumulator: B, value: A) => B): B {\n return this.tail.foldLeft(f(start, this.head), f);\n }\n\n /**\n * Reduces the elements from right to left using an accumulator.\n *\n * @template B The type of the accumulator/result.\n * @param {B} start The initial accumulator value.\n * @param {(value: A, accumulator: B) => B} f A function that combines each element with the accumulator.\n * @returns {B} The final accumulated result.\n *\n * @example\n * NonEmptyList.fromArray([\"a\", \"b\", \"c\"]).foldRight(\"\", (s, acc) => acc + s); // \"cba\"\n */\n public foldRight<B>(start: B, f: (value: A, accumulator: B) => B): B {\n return f(this.head, this.tail.foldRight(start, f));\n }\n\n /**\n * Reduces the elements using a combining function, without requiring an initial value.\n * This is safe because the list is guaranteed to be non-empty.\n *\n * @param {(a: A, b: A) => A} f A function that combines two elements.\n * @returns {A} The result of reducing all elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).reduce((a, b) => a + b); // 6\n * NonEmptyList.pure(42).reduce((a, b) => a + b); // 42\n */\n public reduce(f: (a: A, b: A) => A): A {\n return this.tail.foldLeft(this.head, f);\n }\n\n /**\n * Executes `f` for each element, in order. Returns void.\n *\n * @param {(value: A) => void} f A function called once per element.\n *\n * @example\n * const out: number[] = [];\n * NonEmptyList.fromArray([1, 2, 3]).forEach(n => out.push(n));\n * // out: [1, 2, 3]\n */\n public forEach(f: (value: A) => void): void {\n f(this.head);\n this.tail.forEach(f);\n }\n\n /**\n * Counts the elements that satisfy the predicate.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {number} The number of matching elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4]).count(n => n % 2 === 0); // 2\n */\n public count(predicate: (value: A) => boolean): number {\n return (predicate(this.head) ? 1 : 0) + this.tail.count(predicate);\n }\n\n /**\n * Returns `true` if at least one element satisfies the predicate.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {boolean} `true` if any element matches, `false` otherwise.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).exists(n => n > 2); // true\n * NonEmptyList.fromArray([1, 2, 3]).exists(n => n > 5); // false\n */\n public exists(predicate: (value: A) => boolean): boolean {\n return predicate(this.head) || this.tail.exists(predicate);\n }\n\n /**\n * Returns `true` if all elements satisfy the predicate.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {boolean} `true` if every element matches, `false` otherwise.\n *\n * @example\n * NonEmptyList.fromArray([2, 4, 6]).forall(n => n % 2 === 0); // true\n * NonEmptyList.fromArray([2, 3, 6]).forall(n => n % 2 === 0); // false\n */\n public forall(predicate: (value: A) => boolean): boolean {\n return predicate(this.head) && this.tail.forall(predicate);\n }\n\n /**\n * Returns `true` if the list contains the given value. The optional `eq` function defaults\n * to `Object.is` semantics (so `NaN === NaN` and `+0 !== -0`).\n *\n * @param {A} value The value to look for.\n * @param {(a: A, b: A) => boolean} [eq=Object.is] Optional equality function.\n * @returns {boolean} `true` if a matching element exists.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).contains(2); // true\n * NonEmptyList.fromArray([1, 2, 3]).contains(99); // false\n */\n public contains(value: A, eq: (a: A, b: A) => boolean = Object.is): boolean {\n if (eq(this.head, value)) return true;\n return this.tail.contains(value, eq);\n }\n\n /**\n * Finds the first element that satisfies the predicate.\n *\n * @param {(value: A) => boolean} predicate A function that tests each element.\n * @returns {Option<A>} `Some(value)` if a matching element is found, `None` otherwise.\n *\n * @example\n * NonEmptyList.fromArray([1, 3, 4]).find(x => x % 2 === 0); // Some(4)\n * NonEmptyList.fromArray([1, 3, 5]).find(x => x > 10); // None\n */\n public find(predicate: (value: A) => boolean): Option<A> {\n if (predicate(this.head)) return Some.pure(this.head as NonNullable<A>) as Option<A>;\n return this.tail.find(predicate);\n }\n\n /**\n * Keeps elements satisfying the predicate. Because filtering may remove all elements, the\n * result is a {@link List}, not a `NonEmptyList`.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} A `List` of matching elements (possibly empty).\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4]).filter(n => n > 2).toArray(); // [3, 4]\n * NonEmptyList.fromArray([1, 2]).filter(n => n > 10).toArray(); // []\n */\n public filter(predicate: (value: A) => boolean): List<A> {\n const out: A[] = [];\n if (predicate(this.head)) out.push(this.head);\n for (const item of this.tail.toArray()) {\n if (predicate(item)) out.push(item);\n }\n return List._unsafeFromArray(out);\n }\n\n /**\n * Drops elements satisfying the predicate. Result is a {@link List} since filtering may\n * empty the list.\n *\n * @param {(value: A) => boolean} predicate A predicate; matching elements are removed.\n * @returns {List<A>} A `List` of non-matching elements (possibly empty).\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4]).filterNot(n => n > 2).toArray(); // [1, 2]\n */\n public filterNot(predicate: (value: A) => boolean): List<A> {\n return this.filter((x) => !predicate(x));\n }\n\n /**\n * Applies a partial function returning {@link Option} to each element, keeping only the\n * `Some` results.\n *\n * @template B The result element type.\n * @param {(value: A) => Option<B>} pf A partial function from `A` to `Option<B>`.\n * @returns {List<B>} A `List` of mapped, kept values (possibly empty).\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4])\n * .collect(n => n % 2 === 0 ? Some.pure(n * 10) : None.Instance)\n * .toArray(); // [20, 40]\n */\n public collect<B>(pf: (value: A) => Option<B>): List<B> {\n const out: B[] = [];\n const headR = pf(this.head);\n if (headR instanceof Some) out.push((headR as Some<B>).value);\n for (const item of this.tail.toArray()) {\n const r = pf(item);\n if (r instanceof Some) out.push((r as Some<B>).value);\n }\n return List._unsafeFromArray(out);\n }\n\n /**\n * Splits the list into two: elements matching the predicate, and those not matching.\n * Either side may be empty.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {[List<A>, List<A>]} A tuple of `[matching, nonMatching]`.\n *\n * @example\n * const [evens, odds] = NonEmptyList.fromArray([1, 2, 3, 4, 5]).partition(n => n % 2 === 0);\n * evens.toArray(); // [2, 4]\n * odds.toArray(); // [1, 3, 5]\n */\n public partition(predicate: (value: A) => boolean): [List<A>, List<A>] {\n return this.toList().partition(predicate);\n }\n\n /**\n * Returns a {@link List} of the first `n` elements (or all, if `n >= size`). Returns the\n * empty list when `n <= 0`.\n *\n * @param {number} n The number of elements to take.\n * @returns {List<A>} A `List` of up to `n` elements.\n */\n public take(n: number): List<A> {\n return this.toList().take(n);\n }\n\n /**\n * Returns a {@link List} of all elements after the first `n`. Returns the full list\n * when `n <= 0`, and the empty list when `n >= size`.\n *\n * @param {number} n The number of leading elements to drop.\n * @returns {List<A>} A `List` of remaining elements.\n */\n public drop(n: number): List<A> {\n return this.toList().drop(n);\n }\n\n /**\n * Returns the longest prefix of elements satisfying the predicate, as a {@link List}.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} The prefix of matching elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 1]).takeWhile(n => n < 3).toArray(); // [1, 2]\n */\n public takeWhile(predicate: (value: A) => boolean): List<A> {\n return this.toList().takeWhile(predicate);\n }\n\n /**\n * Drops the longest prefix of elements satisfying the predicate, returning the rest as a\n * {@link List}.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} The suffix of elements after the matching prefix.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 1]).dropWhile(n => n < 3).toArray(); // [3, 1]\n */\n public dropWhile(predicate: (value: A) => boolean): List<A> {\n return this.toList().dropWhile(predicate);\n }\n\n /**\n * Returns the slice `[from, to)` as a {@link List}. Indices are clamped to `[0, size]`.\n *\n * @param {number} from Inclusive start index.\n * @param {number} to Exclusive end index.\n * @returns {List<A>} A `List` of elements in the requested range.\n */\n public slice(from: number, to: number): List<A> {\n return this.toList().slice(from, to);\n }\n\n /**\n * Appends an element to the end, returning a new `NonEmptyList`.\n *\n * @param {A} value The element to append.\n * @returns {NonEmptyList<A>} A new list with the element at the end.\n *\n * @example\n * NonEmptyList.fromArray([1, 2]).append(3).toArray(); // [1, 2, 3]\n */\n public append(value: A): NonEmptyList<A> {\n return new NonEmptyList(this.head, List._unsafeFromArray([...this.tail.toArray(), value]));\n }\n\n /**\n * Prepends an element to the beginning, returning a new `NonEmptyList`.\n *\n * @param {A} value The element to place at the front.\n * @returns {NonEmptyList<A>} A new list with the element at the beginning.\n *\n * @example\n * NonEmptyList.fromArray([2, 3]).prepend(1).toArray(); // [1, 2, 3]\n */\n public prepend(value: A): NonEmptyList<A> {\n return new NonEmptyList(value, List._unsafeFromArray([this.head, ...this.tail.toArray()]));\n }\n\n /**\n * Concatenates with another `NonEmptyList`. Result remains non-empty.\n *\n * @param {NonEmptyList<A>} other The list to concatenate.\n * @returns {NonEmptyList<A>} A new list containing all elements of both.\n *\n * @example\n * const a = NonEmptyList.fromArray([1, 2]);\n * const b = NonEmptyList.fromArray([3, 4]);\n * a.concat(b).toArray(); // [1, 2, 3, 4]\n */\n public concat(other: NonEmptyList<A>): NonEmptyList<A>;\n /**\n * Concatenates with a possibly-empty {@link List}. Result remains non-empty since the\n * receiver is.\n *\n * @param {List<A>} other The list to concatenate.\n * @returns {NonEmptyList<A>} A new `NonEmptyList` containing all elements of both.\n *\n * @example\n * NonEmptyList.fromArray([1, 2]).concat(List.of(3, 4)).toArray(); // [1, 2, 3, 4]\n * NonEmptyList.fromArray([1, 2]).concat(List.empty<number>()).toArray(); // [1, 2]\n */\n public concat(other: List<A>): NonEmptyList<A>;\n public concat(other: List<A> | NonEmptyList<A>): NonEmptyList<A> {\n return new NonEmptyList(this.head, List._unsafeFromArray([...this.tail.toArray(), ...other.toArray()]));\n }\n\n /**\n * Reverses the order of elements, returning a new `NonEmptyList`.\n *\n * @returns {NonEmptyList<A>} A new list with elements in reverse order.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).reverse().toArray(); // [3, 2, 1]\n */\n public reverse(): NonEmptyList<A> {\n const arr = this.toArray().reverse();\n return new NonEmptyList(arr[0], List._unsafeFromArray(arr.slice(1)));\n }\n\n /**\n * Sorts the elements using an {@link Ordering}-returning comparator.\n *\n * @param {(a: A, b: A) => Ordering} comparator A function that compares two elements.\n * @returns {NonEmptyList<A>} A new sorted `NonEmptyList`.\n *\n * @example\n * NonEmptyList.fromArray([3, 1, 2]).sort((a, b) =>\n * a < b ? Ordering.LessThan : a > b ? Ordering.GreaterThan : Ordering.Equal\n * );\n * // NonEmptyList [1, 2, 3]\n */\n public sort(comparator: (a: A, b: A) => Ordering): NonEmptyList<A> {\n const sorted = this.toArray().sort((a, b) => comparator(a, b).value);\n return new NonEmptyList(sorted[0], List._unsafeFromArray(sorted.slice(1)));\n }\n\n /**\n * Sorts the elements by a key extracted from each element.\n *\n * @template K The key type.\n * @param {(value: A) => K} f Extracts the comparison key.\n * @param {(a: K, b: K) => Ordering} comparator Compares two keys.\n * @returns {NonEmptyList<A>} A new sorted `NonEmptyList`.\n *\n * @example\n * NonEmptyList.fromArray([{ id: 3 }, { id: 1 }])\n * .sortBy(u => u.id, (a, b) => a < b ? Ordering.LessThan : a > b ? Ordering.GreaterThan : Ordering.Equal);\n * // NonEmptyList [{ id: 1 }, { id: 3 }]\n */\n public sortBy<K>(f: (value: A) => K, comparator: (a: K, b: K) => Ordering): NonEmptyList<A> {\n const sorted = this.toArray().sort((a, b) => comparator(f(a), f(b)).value);\n return new NonEmptyList(sorted[0], List._unsafeFromArray(sorted.slice(1)));\n }\n\n /**\n * Removes duplicates, keeping the first occurrence of each value. Equality defaults to\n * `Object.is`. Result remains non-empty since the head always survives.\n *\n * @param {(a: A, b: A) => boolean} [eq=Object.is] Optional equality function.\n * @returns {NonEmptyList<A>} A new `NonEmptyList` with duplicates removed.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 1, 3, 2]).distinct().toArray(); // [1, 2, 3]\n */\n public distinct(eq: (a: A, b: A) => boolean = Object.is): NonEmptyList<A> {\n const arr = this.toList().distinct(eq).toArray();\n return new NonEmptyList(arr[0], List._unsafeFromArray(arr.slice(1)));\n }\n\n /**\n * Inserts `sep` between adjacent elements. For a single-element list this is a no-op.\n *\n * @param {A} sep The separator to interleave.\n * @returns {NonEmptyList<A>} A new `NonEmptyList` with `sep` between original elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).intersperse(0).toArray(); // [1, 0, 2, 0, 3]\n * NonEmptyList.pure(1).intersperse(0).toArray(); // [1]\n */\n public intersperse(sep: A): NonEmptyList<A> {\n if (this.tail.isEmpty) return this;\n const tailArr = this.tail.toArray();\n const out: A[] = [];\n for (let i = 0; i < tailArr.length; i++) {\n out.push(sep, tailArr[i]);\n }\n return new NonEmptyList(this.head, List._unsafeFromArray(out));\n }\n\n /**\n * Joins string representations of the elements using a separator.\n *\n * @param {string} [separator=\"\"] The string to place between elements.\n * @returns {string} The joined string.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).mkString(\", \"); // \"1, 2, 3\"\n * NonEmptyList.fromArray([\"a\", \"b\"]).mkString(\"-\"); // \"a-b\"\n */\n public mkString(separator: string = \"\"): string {\n return this.toArray().join(separator);\n }\n\n /**\n * Pairs elements with another `NonEmptyList`. Both being non-empty guarantees a non-empty\n * result.\n *\n * @template B The element type of the other list.\n * @param {NonEmptyList<B>} other The other list.\n * @returns {NonEmptyList<[A, B]>} A `NonEmptyList` of pairs.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).zip(NonEmptyList.fromArray([\"a\", \"b\", \"c\"])).toArray();\n * // [[1, \"a\"], [2, \"b\"], [3, \"c\"]]\n */\n public zip<B>(other: NonEmptyList<B>): NonEmptyList<[A, B]>;\n /**\n * Pairs elements with a possibly-empty {@link List}. If the other list is empty, the\n * result is empty.\n *\n * @template B The element type of the other list.\n * @param {List<B>} other The other list.\n * @returns {List<[A, B]>} A `List` of pairs (possibly empty).\n */\n public zip<B>(other: List<B>): List<[A, B]>;\n public zip<B>(other: List<B> | NonEmptyList<B>): List<[A, B]> | NonEmptyList<[A, B]> {\n if (other instanceof NonEmptyList) {\n const tailA = this.tail.toArray();\n const tailB = other.tail.toArray();\n const n = Math.min(tailA.length, tailB.length);\n const tail: [A, B][] = new Array(n);\n for (let i = 0; i < n; i++) tail[i] = [tailA[i], tailB[i]];\n return new NonEmptyList<[A, B]>([this.head, other.head], List._unsafeFromArray(tail));\n }\n return this.toList().zip(other);\n }\n\n /**\n * Combines paired elements via `f`. With another `NonEmptyList`, the result is non-empty.\n *\n * @template B The element type of the other list.\n * @template C The result element type.\n * @param {NonEmptyList<B>} other The other list.\n * @param {(a: A, b: B) => C} f Combines a pair of elements.\n * @returns {NonEmptyList<C>} A `NonEmptyList` of combined values.\n */\n public zipWith<B, C>(other: NonEmptyList<B>, f: (a: A, b: B) => C): NonEmptyList<C>;\n /**\n * Combines paired elements via `f`. Stops at the shorter list; may be empty.\n *\n * @template B The element type of the other list.\n * @template C The result element type.\n * @param {List<B>} other The other list.\n * @param {(a: A, b: B) => C} f Combines a pair of elements.\n * @returns {List<C>} A `List` of combined values.\n */\n public zipWith<B, C>(other: List<B>, f: (a: A, b: B) => C): List<C>;\n public zipWith<B, C>(other: List<B> | NonEmptyList<B>, f: (a: A, b: B) => C): List<C> | NonEmptyList<C> {\n if (other instanceof NonEmptyList) {\n const tailA = this.tail.toArray();\n const tailB = other.tail.toArray();\n const n = Math.min(tailA.length, tailB.length);\n const tail: C[] = new Array(n);\n for (let i = 0; i < n; i++) tail[i] = f(tailA[i], tailB[i]);\n return new NonEmptyList<C>(f(this.head, other.head), List._unsafeFromArray(tail));\n }\n return this.toList().zipWith(other, f);\n }\n\n /**\n * Pairs each element with its zero-based index. Result remains non-empty.\n *\n * @returns {NonEmptyList<[A, number]>} A `NonEmptyList` of `[element, index]` pairs.\n *\n * @example\n * NonEmptyList.fromArray([\"a\", \"b\", \"c\"]).zipWithIndex().toArray();\n * // [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n */\n public zipWithIndex(): NonEmptyList<[A, number]> {\n const tailArr = this.tail.toArray();\n const tail: [A, number][] = new Array(tailArr.length);\n for (let i = 0; i < tailArr.length; i++) tail[i] = [tailArr[i], i + 1];\n return new NonEmptyList<[A, number]>([this.head, 0], List._unsafeFromArray(tail));\n }\n\n /**\n * Groups elements by a key extracted via `f`. Iteration order in the resulting `Map`\n * reflects the order each key was first encountered. Each group is non-empty by\n * construction.\n *\n * @template K The key type.\n * @param {(value: A) => K} f Extracts the group key.\n * @returns {Map<K, NonEmptyList<A>>} A `Map` of group keys to their members.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4, 5]).groupBy(n => n % 2);\n * // Map { 1 => NEL[1, 3, 5], 0 => NEL[2, 4] }\n */\n public groupBy<K>(f: (value: A) => K): Map<K, NonEmptyList<A>> {\n return this.toList().groupBy(f);\n }\n\n /**\n * Splits the list into consecutive chunks of size `n`. The last chunk may be smaller. The\n * outer and inner lists are both `NonEmptyList`.\n *\n * @param {number} n The maximum chunk size; must be positive.\n * @returns {NonEmptyList<NonEmptyList<A>>} A non-empty list of non-empty chunks.\n * @throws {Error} If `n <= 0`.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3, 4, 5]).chunk(2).toArray().map(c => c.toArray());\n * // [[1, 2], [3, 4], [5]]\n */\n public chunk(n: number): NonEmptyList<NonEmptyList<A>> {\n if (n <= 0) throw new Error(\"NonEmptyList.chunk size must be positive.\");\n const arr = this.toArray();\n const chunks: NonEmptyList<A>[] = [];\n for (let i = 0; i < arr.length; i += n) {\n const slice = arr.slice(i, i + n);\n chunks.push(new NonEmptyList(slice[0], List._unsafeFromArray(slice.slice(1))));\n }\n return new NonEmptyList(chunks[0], List._unsafeFromArray(chunks.slice(1)));\n }\n\n /**\n * Lifts a function `A => F<B>` over the list, producing `F<NonEmptyList<B>>` — where `F` is\n * one of the library's effect types. The first argument selects the effect; the return type\n * and evaluation strategy follow from it. Receiver is non-empty so the result is always\n * `F<NonEmptyList<B>>`.\n *\n * - `traverse(IO, f)` — sequential, fails fast on the first error (uses `IO`'s flatMap).\n * - `traverse(Either, f)` — short-circuits on the first `Left`.\n * - `traverse(Option, f)` — short-circuits on the first `None`.\n * - `traverse(Promise, f)` — parallel via `Promise.all`. For sequential async use\n * `traverse(IO, n => IO.lift(async () => …))` — IO is the proper sequential type.\n *\n * @example\n * await nel.traverse(IO, (n) => IO.lift(() => n * 10)).unsafeRun();\n * nel.traverse(Either, (n) => n > 0 ? Right.pure(n) : Left.pure(\"bad\"));\n * nel.traverse(Option, (n) => n > 0 ? Some.pure(n) : None.Instance);\n * await nel.traverse(Promise, async (n) => n * 2);\n */\n public traverse<E, B>(eff: typeof IO, f: (value: A) => IO<E, B>): IO<E, NonEmptyList<B>>;\n public traverse<L, B>(eff: typeof Either, f: (value: A) => Either<L, B>): Either<L, NonEmptyList<B>>;\n public traverse<B>(eff: typeof Option, f: (value: A) => Option<B>): Option<NonEmptyList<B>>;\n public traverse<B>(eff: PromiseConstructor, f: (value: A) => Promise<B>): Promise<NonEmptyList<B>>;\n public traverse(eff: unknown, f: (value: A) => unknown): unknown {\n if (eff === IO) {\n return IO.traverse(this.toArray(), f as (a: A) => IO<unknown, unknown>).map((list) =>\n NonEmptyList._unsafeFromArray(list.toArray())\n );\n }\n if (eff === Either) {\n const headR = f(this.head);\n if (headR instanceof Left) return headR;\n const tailOut: unknown[] = [];\n for (const item of this.tail.toArray()) {\n const r = f(item);\n if (r instanceof Left) return r;\n tailOut.push((r as Right<unknown>).value);\n }\n return Right.pure(new NonEmptyList((headR as Right<unknown>).value, List._unsafeFromArray(tailOut)));\n }\n if (eff === Option) {\n const headR = f(this.head);\n if (!(headR instanceof Some)) return None.Instance;\n const tailOut: unknown[] = [];\n for (const item of this.tail.toArray()) {\n const r = f(item);\n if (!(r instanceof Some)) return None.Instance;\n tailOut.push((r as Some<unknown>).value);\n }\n return Some.pure(\n new NonEmptyList((headR as Some<unknown>).value, List._unsafeFromArray(tailOut)) as NonNullable<\n NonEmptyList<unknown>\n >\n );\n }\n if (eff === Promise) {\n const fn = f as (a: A) => Promise<unknown>;\n return Promise.all([fn(this.head), ...this.tail.toArray().map(fn)]).then(\n ([headResult, ...tailResults]) => new NonEmptyList(headResult, List._unsafeFromArray(tailResults))\n );\n }\n throw new Error(\n `NonEmptyList.traverse: unknown effect type — expected IO, Either, Option, or Promise, got ${String(eff)}`\n );\n }\n\n /**\n * Returns a string representation of the `NonEmptyList`.\n *\n * @returns {string} A string showing all elements.\n *\n * @example\n * NonEmptyList.fromArray([1, 2, 3]).toString(); // \"[1, 2, 3]\"\n */\n public toString(): string {\n return `[${this.toArray().join(\", \")}]`;\n }\n}\n","import { Either, Left, Right } from \"./either\";\nimport { IO } from \"./io\";\nimport { NonEmptyList } from \"./non-empty-list\";\nimport { None, Option, Some } from \"./option\";\nimport { Ordering } from \"./ordering\";\n\n/**\n * An immutable, possibly-empty list with FP-style operations.\n *\n * `List<A>` is the general-purpose counterpart to {@link NonEmptyList}. Operations that may\n * remove all elements (`filter`, `filterNot`, `collect`, `partition`, `take`, `drop`,\n * `takeWhile`, `dropWhile`, `slice`) return `List<A>`. Operations that preserve or guarantee\n * non-emptiness (`append`, `prepend`, `concat` with a `NonEmptyList`) return `NonEmptyList<A>`.\n *\n * Instances are immutable; every operation returns a new instance. The backing array is\n * defensively copied on construction so user-supplied arrays can be mutated freely afterwards.\n *\n * @template A The type of elements in the list.\n */\nexport class List<A> {\n private constructor(private readonly _items: readonly A[]) {}\n\n /**\n * Constructs a `List` without copying the input array. The caller must guarantee that the\n * passed array will not be mutated. This is used internally by {@link NonEmptyList} and the\n * library's traverse implementations to avoid redundant allocations.\n *\n * @internal\n */\n public static _unsafeFromArray<A>(values: readonly A[]): List<A> {\n return new List<A>(values);\n }\n\n /**\n * Returns the empty `List`.\n *\n * @template A The element type.\n * @returns {List<A>} An empty `List<A>`.\n *\n * @example\n * List.empty<number>().isEmpty; // true\n */\n public static empty<A>(): List<A> {\n return new List<A>([]);\n }\n\n /**\n * Creates a `List` with a single element.\n *\n * @template A The element type.\n * @param {A} value The single element.\n * @returns {List<A>} A `List` containing exactly `value`.\n *\n * @example\n * List.pure(42).toArray(); // [42]\n */\n public static pure<A>(value: A): List<A> {\n return new List<A>([value]);\n }\n\n /**\n * Creates a `List` from a variadic argument list.\n *\n * @template A The element type.\n * @param {...A[]} values The elements, in order.\n * @returns {List<A>} A `List` containing the given elements.\n *\n * @example\n * List.of(1, 2, 3).toArray(); // [1, 2, 3]\n * List.of<number>().toArray(); // []\n */\n public static of<A>(...values: A[]): List<A> {\n return new List<A>(values.slice());\n }\n\n /**\n * Creates a `List` from an array. The input is copied; later mutations to the source array\n * do not affect the resulting `List`.\n *\n * @template A The element type.\n * @param {readonly A[]} values The source array.\n * @returns {List<A>} A `List` containing a copy of the array's elements.\n *\n * @example\n * const arr = [1, 2, 3];\n * const l = List.fromArray(arr);\n * arr.push(4);\n * l.toArray(); // [1, 2, 3] — unaffected\n */\n public static fromArray<A>(values: readonly A[]): List<A> {\n return new List<A>(values.slice());\n }\n\n /**\n * Widens a {@link NonEmptyList} to a `List`. Equivalent to `nel.toList()`.\n *\n * @template A The element type.\n * @param {NonEmptyList<A>} nel The non-empty list.\n * @returns {List<A>} A `List` view of the same elements.\n *\n * @example\n * List.fromNel(NonEmptyList.fromArray([1, 2, 3])).toArray(); // [1, 2, 3]\n */\n public static fromNel<A>(nel: NonEmptyList<A>): List<A> {\n return new List<A>(nel.toArray());\n }\n\n /**\n * Creates a `List` of integers from `start` (inclusive) to `endExclusive`, stepping by `step`.\n *\n * If `step > 0` and `endExclusive <= start`, or `step < 0` and `endExclusive >= start`,\n * returns the empty list.\n *\n * @param {number} start The first value.\n * @param {number} endExclusive The exclusive end value.\n * @param {number} [step=1] The increment between successive values. Must be non-zero.\n * @returns {List<number>} A `List<number>` of the requested range.\n * @throws {Error} If `step` is zero.\n *\n * @example\n * List.range(0, 5).toArray(); // [0, 1, 2, 3, 4]\n * List.range(0, 10, 2).toArray(); // [0, 2, 4, 6, 8]\n * List.range(5, 0, -1).toArray(); // [5, 4, 3, 2, 1]\n * List.range(5, 5).toArray(); // []\n */\n public static range(start: number, endExclusive: number, step: number = 1): List<number> {\n if (step === 0) throw new Error(\"List.range step must be non-zero.\");\n const out: number[] = [];\n if (step > 0) {\n for (let i = start; i < endExclusive; i += step) out.push(i);\n } else {\n for (let i = start; i > endExclusive; i += step) out.push(i);\n }\n return new List(out);\n }\n\n /**\n * Creates a `List` of length `n` where every element is `value`. Returns the empty list\n * when `n <= 0`.\n *\n * @template A The element type.\n * @param {number} n The number of repetitions.\n * @param {A} value The value to repeat.\n * @returns {List<A>} A `List` of `n` copies of `value`.\n *\n * @example\n * List.fill(3, \"x\").toArray(); // [\"x\", \"x\", \"x\"]\n * List.fill(0, \"x\").toArray(); // []\n */\n public static fill<A>(n: number, value: A): List<A> {\n if (n <= 0) return List.empty();\n return new List<A>(new Array(n).fill(value));\n }\n\n /**\n * The number of elements in the `List`.\n *\n * @returns {number} The element count.\n */\n public get size(): number {\n return this._items.length;\n }\n\n /**\n * `true` if the `List` has no elements.\n *\n * @returns {boolean} Whether the list is empty.\n */\n public get isEmpty(): boolean {\n return this._items.length === 0;\n }\n\n /**\n * `true` if the `List` has at least one element. Equivalent to `!isEmpty`.\n *\n * @returns {boolean} Whether the list has at least one element.\n */\n public get nonEmpty(): boolean {\n return this._items.length > 0;\n }\n\n /**\n * The first element wrapped in {@link Option}.\n *\n * @returns {Option<A>} `Some(head)` if non-empty, `None` otherwise.\n *\n * @example\n * List.of(1, 2, 3).head; // Some(1)\n * List.empty<number>().head; // None\n */\n public get head(): Option<A> {\n return this._items.length === 0\n ? (None.Instance as Option<A>)\n : (Some.pure(this._items[0] as NonNullable<A>) as Option<A>);\n }\n\n /**\n * The last element wrapped in {@link Option}.\n *\n * @returns {Option<A>} `Some(last)` if non-empty, `None` otherwise.\n *\n * @example\n * List.of(1, 2, 3).last; // Some(3)\n * List.empty<number>().last; // None\n */\n public get last(): Option<A> {\n return this._items.length === 0\n ? (None.Instance as Option<A>)\n : (Some.pure(this._items[this._items.length - 1] as NonNullable<A>) as Option<A>);\n }\n\n /**\n * All elements except the first, as a new `List`. Returns the empty list when the list has\n * 0 or 1 elements.\n *\n * @returns {List<A>} The tail of the list.\n *\n * @example\n * List.of(1, 2, 3).tail.toArray(); // [2, 3]\n * List.of(1).tail.toArray(); // []\n * List.empty<number>().tail.toArray(); // []\n */\n public get tail(): List<A> {\n return this._items.length <= 1 ? List.empty() : new List(this._items.slice(1));\n }\n\n /**\n * All elements except the last, as a new `List`. Returns the empty list when the list has\n * 0 or 1 elements.\n *\n * @returns {List<A>} All elements except the last.\n *\n * @example\n * List.of(1, 2, 3).init.toArray(); // [1, 2]\n * List.of(1).init.toArray(); // []\n */\n public get init(): List<A> {\n return this._items.length <= 1 ? List.empty() : new List(this._items.slice(0, -1));\n }\n\n /**\n * Splits the list into its head and tail.\n *\n * @returns {Option<[A, List<A>]>} `Some([head, tail])` if non-empty, `None` otherwise.\n *\n * @example\n * const opt = List.of(1, 2, 3).uncons; // Some([1, List [2, 3]])\n * List.empty<number>().uncons; // None\n */\n public get uncons(): Option<[A, List<A>]> {\n if (this._items.length === 0) return None.Instance as Option<[A, List<A>]>;\n const tuple: [A, List<A>] = [this._items[0], new List(this._items.slice(1))];\n return Some.pure(tuple as NonNullable<[A, List<A>]>) as Option<[A, List<A>]>;\n }\n\n /**\n * Returns the element at index `i` wrapped in {@link Option}. Out-of-bounds indices yield\n * `None` rather than throwing.\n *\n * @param {number} i Zero-based index.\n * @returns {Option<A>} `Some(element)` if in bounds, `None` otherwise.\n *\n * @example\n * List.of(10, 20, 30).get(1); // Some(20)\n * List.of(10, 20, 30).get(99); // None\n * List.of(10, 20, 30).get(-1); // None\n */\n public get(i: number): Option<A> {\n if (i < 0 || i >= this._items.length) return None.Instance as Option<A>;\n return Some.pure(this._items[i] as NonNullable<A>) as Option<A>;\n }\n\n /**\n * Returns a fresh array copy of the elements.\n *\n * @returns {A[]} A new array containing all elements.\n *\n * @example\n * List.of(1, 2, 3).toArray(); // [1, 2, 3]\n */\n public toArray(): A[] {\n return this._items.slice();\n }\n\n /**\n * Narrows to a {@link NonEmptyList}.\n *\n * @returns {Option<NonEmptyList<A>>} `Some(nel)` if non-empty, `None` otherwise.\n *\n * @example\n * List.of(1, 2, 3).toNel(); // Some(NonEmptyList [1, 2, 3])\n * List.empty<number>().toNel(); // None\n */\n public toNel(): Option<NonEmptyList<A>> {\n if (this._items.length === 0) return None.Instance as Option<NonEmptyList<A>>;\n return Some.pure(\n new NonEmptyList<A>(this._items[0], new List(this._items.slice(1))) as NonNullable<NonEmptyList<A>>\n ) as Option<NonEmptyList<A>>;\n }\n\n /**\n * Applies a function to each element, producing a new `List` of the same length.\n *\n * @template B The result element type.\n * @param {(value: A) => B} f A function applied to each element.\n * @returns {List<B>} A new `List` with the transformed elements.\n *\n * @example\n * List.of(1, 2, 3).map(n => n * 2).toArray(); // [2, 4, 6]\n */\n public map<B>(f: (value: A) => B): List<B> {\n return new List(this._items.map(f));\n }\n\n /**\n * Maps each element to a `List` and concatenates the results.\n *\n * @template B The result element type.\n * @param {(value: A) => List<B>} f A function producing a `List` for each element.\n * @returns {List<B>} A flattened `List` of the results.\n *\n * @example\n * List.of(1, 2, 3).flatMap(n => List.of(n, n * 10)).toArray();\n * // [1, 10, 2, 20, 3, 30]\n */\n public flatMap<B>(f: (value: A) => List<B>): List<B> {\n const out: B[] = [];\n for (const item of this._items) {\n for (const b of f(item)._items) out.push(b);\n }\n return new List(out);\n }\n\n /**\n * Flattens a `List<List<B>>` by one level. Empty inner lists are silently dropped.\n *\n * @template B The inner element type.\n * @returns {List<B>} A flattened `List`.\n *\n * @example\n * List.of(List.of(1, 2), List.empty<number>(), List.of(3)).flatten().toArray();\n * // [1, 2, 3]\n */\n public flatten<B>(this: List<List<B>>): List<B> {\n return this.flatMap((x) => x);\n }\n\n /**\n * Reduces the elements from left to right using an accumulator.\n *\n * @template B The accumulator/result type.\n * @param {B} start The initial accumulator value.\n * @param {(accumulator: B, value: A) => B} f Combines the accumulator with each element.\n * @returns {B} The final accumulated result. Returns `start` for the empty list.\n *\n * @example\n * List.of(1, 2, 3).foldLeft(0, (acc, n) => acc + n); // 6\n * List.empty<number>().foldLeft(7, (acc, n) => acc + n); // 7\n */\n public foldLeft<B>(start: B, f: (accumulator: B, value: A) => B): B {\n return this._items.reduce(f, start);\n }\n\n /**\n * Reduces the elements from right to left using an accumulator.\n *\n * @template B The accumulator/result type.\n * @param {B} start The initial accumulator value.\n * @param {(value: A, accumulator: B) => B} f Combines each element with the accumulator.\n * @returns {B} The final accumulated result. Returns `start` for the empty list.\n *\n * @example\n * List.of(\"a\", \"b\", \"c\").foldRight(\"\", (v, acc) => acc + v); // \"cba\"\n */\n public foldRight<B>(start: B, f: (value: A, accumulator: B) => B): B {\n return this._items.reduceRight((acc, v) => f(v, acc), start);\n }\n\n /**\n * Combines elements pairwise without an initial value. Returns `None` for the empty list,\n * which is why the return type is `Option<A>` (unlike `NonEmptyList#reduce`, which is total).\n *\n * @param {(a: A, b: A) => A} f Combines two elements.\n * @returns {Option<A>} `Some(result)` if non-empty, `None` otherwise.\n *\n * @example\n * List.of(1, 2, 3).reduce((a, b) => a + b); // Some(6)\n * List.empty<number>().reduce((a, b) => a + b); // None\n */\n public reduce(f: (a: A, b: A) => A): Option<A> {\n if (this._items.length === 0) return None.Instance as Option<A>;\n let acc = this._items[0];\n for (let i = 1; i < this._items.length; i++) acc = f(acc, this._items[i]);\n return Some.pure(acc as NonNullable<A>) as Option<A>;\n }\n\n /**\n * Executes `f` for each element, in order. Returns void.\n *\n * @param {(value: A) => void} f A function called once per element.\n *\n * @example\n * const out: number[] = [];\n * List.of(1, 2, 3).forEach(n => out.push(n));\n * // out: [1, 2, 3]\n */\n public forEach(f: (value: A) => void): void {\n for (const item of this._items) f(item);\n }\n\n /**\n * Counts the elements that satisfy the predicate.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {number} The number of matching elements.\n *\n * @example\n * List.of(1, 2, 3, 4).count(n => n % 2 === 0); // 2\n */\n public count(predicate: (value: A) => boolean): number {\n let n = 0;\n for (const item of this._items) if (predicate(item)) n++;\n return n;\n }\n\n /**\n * Returns `true` if at least one element satisfies the predicate.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {boolean} `true` if any element matches, `false` otherwise (including the empty list).\n *\n * @example\n * List.of(1, 2, 3).exists(n => n > 2); // true\n * List.empty<number>().exists(n => n > 0); // false\n */\n public exists(predicate: (value: A) => boolean): boolean {\n return this._items.some(predicate);\n }\n\n /**\n * Returns `true` if every element satisfies the predicate. Vacuously `true` for the empty\n * list.\n *\n * @param {(value: A) => boolean} predicate A function to test each element.\n * @returns {boolean} `true` if every element matches.\n *\n * @example\n * List.of(2, 4, 6).forall(n => n % 2 === 0); // true\n * List.of(2, 3, 6).forall(n => n % 2 === 0); // false\n * List.empty<number>().forall(n => false); // true (vacuous)\n */\n public forall(predicate: (value: A) => boolean): boolean {\n return this._items.every(predicate);\n }\n\n /**\n * Returns `true` if the list contains the given value. The optional `eq` function defaults\n * to `Object.is` semantics (so `NaN === NaN` and `+0 !== -0`).\n *\n * @param {A} value The value to look for.\n * @param {(a: A, b: A) => boolean} [eq=Object.is] Optional equality function.\n * @returns {boolean} `true` if a matching element exists.\n *\n * @example\n * List.of(1, 2, 3).contains(2); // true\n * List.of(1, 2, 3).contains(99); // false\n */\n public contains(value: A, eq: (a: A, b: A) => boolean = Object.is): boolean {\n for (const item of this._items) if (eq(item, value)) return true;\n return false;\n }\n\n /**\n * Finds the first element that satisfies the predicate.\n *\n * @param {(value: A) => boolean} predicate A function that tests each element.\n * @returns {Option<A>} `Some(value)` if a match is found, `None` otherwise.\n *\n * @example\n * List.of(1, 3, 4).find(x => x % 2 === 0); // Some(4)\n * List.of(1, 3, 5).find(x => x > 10); // None\n */\n public find(predicate: (value: A) => boolean): Option<A> {\n const i = this._items.findIndex(predicate);\n if (i === -1) return None.Instance as Option<A>;\n return Some.pure(this._items[i] as NonNullable<A>) as Option<A>;\n }\n\n /**\n * Finds the index of the first element satisfying the predicate.\n *\n * @param {(value: A) => boolean} predicate A function that tests each element.\n * @returns {Option<number>} `Some(index)` if a match is found, `None` otherwise.\n *\n * @example\n * List.of(10, 20, 30).findIndex(n => n === 20); // Some(1)\n * List.of(10, 20).findIndex(n => n === 99); // None\n */\n public findIndex(predicate: (value: A) => boolean): Option<number> {\n const i = this._items.findIndex(predicate);\n if (i === -1) return None.Instance as Option<number>;\n return Some.pure(i as NonNullable<number>) as Option<number>;\n }\n\n /**\n * Keeps the elements satisfying the predicate.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} A `List` of matching elements (possibly empty).\n *\n * @example\n * List.of(1, 2, 3, 4).filter(n => n % 2 === 0).toArray(); // [2, 4]\n */\n public filter(predicate: (value: A) => boolean): List<A> {\n return new List(this._items.filter(predicate));\n }\n\n /**\n * Drops the elements satisfying the predicate.\n *\n * @param {(value: A) => boolean} predicate A predicate; matching elements are removed.\n * @returns {List<A>} A `List` of non-matching elements (possibly empty).\n *\n * @example\n * List.of(1, 2, 3, 4).filterNot(n => n % 2 === 0).toArray(); // [1, 3]\n */\n public filterNot(predicate: (value: A) => boolean): List<A> {\n return new List(this._items.filter((x) => !predicate(x)));\n }\n\n /**\n * Applies a partial function returning {@link Option} to each element, keeping only the\n * `Some` results. This is the standard \"filter and map at once\" pattern.\n *\n * @template B The result element type.\n * @param {(value: A) => Option<B>} pf A partial function from `A` to `Option<B>`.\n * @returns {List<B>} A `List` of mapped, kept values (possibly empty).\n *\n * @example\n * List.of(1, 2, 3, 4)\n * .collect(n => n % 2 === 0 ? Some.pure(n * 10) : None.Instance)\n * .toArray();\n * // [20, 40]\n */\n public collect<B>(pf: (value: A) => Option<B>): List<B> {\n const out: B[] = [];\n for (const item of this._items) {\n const r = pf(item);\n if (r instanceof Some) out.push((r as Some<B>).value);\n }\n return new List(out);\n }\n\n /**\n * Splits the list into matching and non-matching elements.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {[List<A>, List<A>]} A tuple of `[matching, nonMatching]`.\n *\n * @example\n * const [evens, odds] = List.of(1, 2, 3, 4, 5).partition(n => n % 2 === 0);\n * evens.toArray(); // [2, 4]\n * odds.toArray(); // [1, 3, 5]\n */\n public partition(predicate: (value: A) => boolean): [List<A>, List<A>] {\n const yes: A[] = [];\n const no: A[] = [];\n for (const item of this._items) (predicate(item) ? yes : no).push(item);\n return [new List(yes), new List(no)];\n }\n\n /**\n * Returns the first `n` elements. Returns the empty list when `n <= 0`, or the whole list\n * when `n >= size`.\n *\n * @param {number} n The number of elements to take.\n * @returns {List<A>} A `List` of up to `n` elements.\n *\n * @example\n * List.of(1, 2, 3, 4).take(2).toArray(); // [1, 2]\n * List.of(1, 2, 3, 4).take(99).toArray(); // [1, 2, 3, 4]\n */\n public take(n: number): List<A> {\n if (n <= 0) return List.empty();\n return new List(this._items.slice(0, n));\n }\n\n /**\n * Returns all elements after the first `n`. Returns the whole list when `n <= 0`, or the\n * empty list when `n >= size`.\n *\n * @param {number} n The number of leading elements to drop.\n * @returns {List<A>} A `List` of remaining elements.\n *\n * @example\n * List.of(1, 2, 3, 4).drop(2).toArray(); // [3, 4]\n * List.of(1, 2, 3, 4).drop(99).toArray(); // []\n */\n public drop(n: number): List<A> {\n if (n <= 0) return new List(this._items.slice());\n return new List(this._items.slice(n));\n }\n\n /**\n * Returns the longest prefix of elements satisfying the predicate.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} The matching prefix.\n *\n * @example\n * List.of(1, 2, 3, 1).takeWhile(n => n < 3).toArray(); // [1, 2]\n */\n public takeWhile(predicate: (value: A) => boolean): List<A> {\n const out: A[] = [];\n for (const item of this._items) {\n if (!predicate(item)) break;\n out.push(item);\n }\n return new List(out);\n }\n\n /**\n * Drops the longest prefix of elements satisfying the predicate, returning the rest.\n *\n * @param {(value: A) => boolean} predicate A predicate function.\n * @returns {List<A>} The suffix after the matching prefix.\n *\n * @example\n * List.of(1, 2, 3, 1).dropWhile(n => n < 3).toArray(); // [3, 1]\n */\n public dropWhile(predicate: (value: A) => boolean): List<A> {\n let i = 0;\n while (i < this._items.length && predicate(this._items[i])) i++;\n return new List(this._items.slice(i));\n }\n\n /**\n * Returns the slice `[from, to)`. Indices are clamped to `[0, size]`.\n *\n * @param {number} from Inclusive start index.\n * @param {number} to Exclusive end index.\n * @returns {List<A>} A `List` of elements in the requested range.\n *\n * @example\n * List.of(0, 1, 2, 3, 4).slice(1, 4).toArray(); // [1, 2, 3]\n * List.of(0, 1, 2).slice(-5, 99).toArray(); // [0, 1, 2]\n */\n public slice(from: number, to: number): List<A> {\n return new List(this._items.slice(Math.max(0, from), Math.max(0, to)));\n }\n\n /**\n * Appends an element to the end. The result is guaranteed non-empty, so the return type is\n * {@link NonEmptyList}.\n *\n * @param {A} value The element to append.\n * @returns {NonEmptyList<A>} A new `NonEmptyList` with `value` at the end.\n *\n * @example\n * List.empty<number>().append(1).toArray(); // [1]\n * List.of(1, 2).append(3).toArray(); // [1, 2, 3]\n */\n public append(value: A): NonEmptyList<A> {\n if (this._items.length === 0) return new NonEmptyList(value, List.empty<A>());\n return new NonEmptyList(this._items[0], new List([...this._items.slice(1), value]));\n }\n\n /**\n * Prepends an element to the beginning. The result is guaranteed non-empty, so the return\n * type is {@link NonEmptyList}.\n *\n * @param {A} value The element to place at the front.\n * @returns {NonEmptyList<A>} A new `NonEmptyList` with `value` at the front.\n *\n * @example\n * List.of(2, 3).prepend(1).toArray(); // [1, 2, 3]\n */\n public prepend(value: A): NonEmptyList<A> {\n return new NonEmptyList(value, new List(this._items.slice()));\n }\n\n /**\n * Concatenates with a {@link NonEmptyList}. Result is non-empty.\n *\n * @param {NonEmptyList<A>} other The non-empty list to concatenate.\n * @returns {NonEmptyList<A>} A `NonEmptyList` containing all elements of both.\n *\n * @example\n * List.empty<number>().concat(NonEmptyList.fromArray([1, 2])).toArray(); // [1, 2]\n */\n public concat(other: NonEmptyList<A>): NonEmptyList<A>;\n /**\n * Concatenates with another `List`. The result is empty only if both sides are empty.\n *\n * @param {List<A>} other The list to concatenate.\n * @returns {List<A>} A `List` containing all elements of both.\n *\n * @example\n * List.of(1, 2).concat(List.of(3, 4)).toArray(); // [1, 2, 3, 4]\n */\n public concat(other: List<A>): List<A>;\n public concat(other: List<A> | NonEmptyList<A>): List<A> | NonEmptyList<A> {\n if (other instanceof NonEmptyList) {\n const otherArr = other.toArray();\n if (this._items.length === 0) {\n return new NonEmptyList(otherArr[0], new List(otherArr.slice(1)));\n }\n return new NonEmptyList(this._items[0], new List([...this._items.slice(1), ...otherArr]));\n }\n return new List([...this._items, ...other._items]);\n }\n\n /**\n * Reverses the order of elements.\n *\n * @returns {List<A>} A new `List` with elements in reverse order.\n *\n * @example\n * List.of(1, 2, 3).reverse().toArray(); // [3, 2, 1]\n */\n public reverse(): List<A> {\n return new List(this._items.slice().reverse());\n }\n\n /**\n * Sorts using an {@link Ordering}-returning comparator.\n *\n * @param {(a: A, b: A) => Ordering} comparator A function that compares two elements.\n * @returns {List<A>} A new sorted `List`.\n *\n * @example\n * List.of(3, 1, 2).sort((a, b) =>\n * a < b ? Ordering.LessThan : a > b ? Ordering.GreaterThan : Ordering.Equal\n * ).toArray();\n * // [1, 2, 3]\n */\n public sort(comparator: (a: A, b: A) => Ordering): List<A> {\n return new List(this._items.slice().sort((a, b) => comparator(a, b).value));\n }\n\n /**\n * Sorts by a key extracted from each element.\n *\n * @template K The key type.\n * @param {(value: A) => K} f Extracts the comparison key.\n * @param {(a: K, b: K) => Ordering} comparator Compares two keys.\n * @returns {List<A>} A new sorted `List`.\n *\n * @example\n * List.of({ k: 3 }, { k: 1 }, { k: 2 })\n * .sortBy(o => o.k, (a, b) => a < b ? Ordering.LessThan : a > b ? Ordering.GreaterThan : Ordering.Equal);\n * // List [{ k: 1 }, { k: 2 }, { k: 3 }]\n */\n public sortBy<K>(f: (value: A) => K, comparator: (a: K, b: K) => Ordering): List<A> {\n return new List(this._items.slice().sort((a, b) => comparator(f(a), f(b)).value));\n }\n\n /**\n * Removes duplicates, keeping the first occurrence of each value. Equality defaults to\n * `Object.is`.\n *\n * @param {(a: A, b: A) => boolean} [eq=Object.is] Optional equality function.\n * @returns {List<A>} A new `List` with duplicates removed.\n *\n * @example\n * List.of(1, 2, 1, 3, 2).distinct().toArray(); // [1, 2, 3]\n */\n public distinct(eq: (a: A, b: A) => boolean = Object.is): List<A> {\n const out: A[] = [];\n for (const item of this._items) {\n if (!out.some((x) => eq(x, item))) out.push(item);\n }\n return new List(out);\n }\n\n /**\n * Inserts `sep` between adjacent elements. For lists of size 0 or 1, this is a no-op.\n *\n * @param {A} sep The separator to interleave.\n * @returns {List<A>} A new `List` with `sep` between original elements.\n *\n * @example\n * List.of(1, 2, 3).intersperse(0).toArray(); // [1, 0, 2, 0, 3]\n * List.of(1).intersperse(0).toArray(); // [1]\n */\n public intersperse(sep: A): List<A> {\n if (this._items.length <= 1) return new List(this._items.slice());\n const out: A[] = [];\n for (let i = 0; i < this._items.length; i++) {\n if (i > 0) out.push(sep);\n out.push(this._items[i]);\n }\n return new List(out);\n }\n\n /**\n * Joins string representations of the elements using a separator.\n *\n * @param {string} [separator=\"\"] The string to place between elements.\n * @returns {string} The joined string. Empty list yields `\"\"`.\n *\n * @example\n * List.of(1, 2, 3).mkString(\", \"); // \"1, 2, 3\"\n * List.empty<number>().mkString(\", \"); // \"\"\n */\n public mkString(separator: string = \"\"): string {\n return this._items.join(separator);\n }\n\n /**\n * Pairs elements with a {@link NonEmptyList}. Stops at the shorter length; may empty.\n *\n * @template B The element type of the other list.\n * @param {NonEmptyList<B>} other The other list.\n * @returns {List<[A, B]>} A `List` of pairs.\n */\n public zip<B>(other: NonEmptyList<B>): List<[A, B]>;\n /**\n * Pairs elements with another `List`. Stops at the shorter length.\n *\n * @template B The element type of the other list.\n * @param {List<B>} other The other list.\n * @returns {List<[A, B]>} A `List` of pairs.\n *\n * @example\n * List.of(1, 2, 3).zip(List.of(\"a\", \"b\")).toArray();\n * // [[1, \"a\"], [2, \"b\"]]\n */\n public zip<B>(other: List<B>): List<[A, B]>;\n public zip<B>(other: List<B> | NonEmptyList<B>): List<[A, B]> {\n const otherArr = other instanceof NonEmptyList ? other.toArray() : other._items;\n const n = Math.min(this._items.length, otherArr.length);\n const out: [A, B][] = new Array(n);\n for (let i = 0; i < n; i++) out[i] = [this._items[i], otherArr[i]];\n return new List(out);\n }\n\n /**\n * Combines paired elements via `f`. Stops at the shorter list.\n *\n * @template B The element type of the other list.\n * @template C The result element type.\n * @param {List<B>} other The other list.\n * @param {(a: A, b: B) => C} f Combines a pair of elements.\n * @returns {List<C>} A `List` of combined values.\n *\n * @example\n * List.of(1, 2, 3).zipWith(List.of(10, 20, 30), (a, b) => a + b).toArray();\n * // [11, 22, 33]\n */\n public zipWith<B, C>(other: List<B>, f: (a: A, b: B) => C): List<C> {\n const n = Math.min(this._items.length, other._items.length);\n const out: C[] = new Array(n);\n for (let i = 0; i < n; i++) out[i] = f(this._items[i], other._items[i]);\n return new List(out);\n }\n\n /**\n * Pairs each element with its zero-based index.\n *\n * @returns {List<[A, number]>} A `List` of `[element, index]` pairs.\n *\n * @example\n * List.of(\"a\", \"b\", \"c\").zipWithIndex().toArray();\n * // [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n */\n public zipWithIndex(): List<[A, number]> {\n const out: [A, number][] = new Array(this._items.length);\n for (let i = 0; i < this._items.length; i++) out[i] = [this._items[i], i];\n return new List(out);\n }\n\n /**\n * Splits a `List` of pairs into a pair of `List`s.\n *\n * @template B First element type.\n * @template C Second element type.\n * @returns {[List<B>, List<C>]} A tuple of two `List`s with the unpacked components.\n *\n * @example\n * const [as, bs] = List.of<[number, string]>([1, \"a\"], [2, \"b\"]).unzip<number, string>();\n * as.toArray(); // [1, 2]\n * bs.toArray(); // [\"a\", \"b\"]\n */\n public unzip<B, C>(this: List<[B, C]>): [List<B>, List<C>] {\n const bs: B[] = new Array(this._items.length);\n const cs: C[] = new Array(this._items.length);\n for (let i = 0; i < this._items.length; i++) {\n bs[i] = this._items[i][0];\n cs[i] = this._items[i][1];\n }\n return [new List(bs), new List(cs)];\n }\n\n /**\n * Groups elements by a key extracted via `f`. Iteration order in the resulting `Map`\n * reflects the order each key was first encountered. Each group is non-empty by\n * construction.\n *\n * @template K The key type.\n * @param {(value: A) => K} f Extracts the group key.\n * @returns {Map<K, NonEmptyList<A>>} A `Map` of group keys to their members.\n *\n * @example\n * List.of(1, 2, 3, 4, 5).groupBy(n => n % 2);\n * // Map { 1 => NonEmptyList [1, 3, 5], 0 => NonEmptyList [2, 4] }\n */\n public groupBy<K>(f: (value: A) => K): Map<K, NonEmptyList<A>> {\n const buckets = new Map<K, A[]>();\n for (const item of this._items) {\n const k = f(item);\n const existing = buckets.get(k);\n if (existing) existing.push(item);\n else buckets.set(k, [item]);\n }\n const out = new Map<K, NonEmptyList<A>>();\n for (const [k, arr] of buckets) {\n out.set(k, new NonEmptyList(arr[0], new List(arr.slice(1))));\n }\n return out;\n }\n\n /**\n * Splits the list into consecutive chunks of size `n` (the last chunk may be smaller).\n * Each chunk is a {@link NonEmptyList}.\n *\n * @param {number} n The maximum chunk size; must be positive.\n * @returns {List<NonEmptyList<A>>} A `List` of non-empty chunks.\n * @throws {Error} If `n <= 0`.\n *\n * @example\n * List.of(1, 2, 3, 4, 5).chunk(2).toArray().map(c => c.toArray());\n * // [[1, 2], [3, 4], [5]]\n */\n public chunk(n: number): List<NonEmptyList<A>> {\n if (n <= 0) throw new Error(\"List.chunk size must be positive.\");\n const out: NonEmptyList<A>[] = [];\n for (let i = 0; i < this._items.length; i += n) {\n const slice = this._items.slice(i, i + n);\n out.push(new NonEmptyList(slice[0], new List(slice.slice(1))));\n }\n return new List(out);\n }\n\n /**\n * Returns sliding windows of size `n` over the list. If `n > size`, returns the empty list.\n *\n * @param {number} n The window size; must be positive.\n * @returns {List<NonEmptyList<A>>} A `List` of windows.\n * @throws {Error} If `n <= 0`.\n *\n * @example\n * List.of(1, 2, 3, 4).sliding(2).toArray().map(w => w.toArray());\n * // [[1, 2], [2, 3], [3, 4]]\n */\n public sliding(n: number): List<NonEmptyList<A>> {\n if (n <= 0) throw new Error(\"List.sliding size must be positive.\");\n if (n > this._items.length) return List.empty();\n const out: NonEmptyList<A>[] = [];\n for (let i = 0; i + n <= this._items.length; i++) {\n const slice = this._items.slice(i, i + n);\n out.push(new NonEmptyList(slice[0], new List(slice.slice(1))));\n }\n return new List(out);\n }\n\n /**\n * Lifts a function `A => F<B>` over the list, producing `F<List<B>>` — where `F` is one of\n * the library's effect types. The first argument selects the effect; the return type and\n * evaluation strategy follow from it.\n *\n * - `traverse(IO, f)` — sequential, fails fast on the first error (uses `IO`'s flatMap).\n * - `traverse(Either, f)` — short-circuits on the first `Left`.\n * - `traverse(Option, f)` — short-circuits on the first `None`.\n * - `traverse(Promise, f)` — parallel via `Promise.all`. For sequential async use\n * `traverse(IO, n => IO.lift(async () => …))` — IO is the proper sequential type.\n *\n * @example\n * await list.traverse(IO, (n) => IO.lift(() => n * 10)).unsafeRun();\n * list.traverse(Either, (n) => n > 0 ? Right.pure(n) : Left.pure(\"bad\"));\n * list.traverse(Option, (n) => n > 0 ? Some.pure(n) : None.Instance);\n * await list.traverse(Promise, async (n) => n * 2);\n */\n public traverse<E, B>(eff: typeof IO, f: (value: A) => IO<E, B>): IO<E, List<B>>;\n public traverse<L, B>(eff: typeof Either, f: (value: A) => Either<L, B>): Either<L, List<B>>;\n public traverse<B>(eff: typeof Option, f: (value: A) => Option<B>): Option<List<B>>;\n public traverse<B>(eff: PromiseConstructor, f: (value: A) => Promise<B>): Promise<List<B>>;\n public traverse(eff: unknown, f: (value: A) => unknown): unknown {\n if (eff === IO) {\n return IO.traverse(this._items.slice(), f as (a: A) => IO<unknown, unknown>);\n }\n if (eff === Either) {\n const out: unknown[] = [];\n for (const item of this._items) {\n const r = f(item);\n if (r instanceof Left) return r;\n out.push((r as Right<unknown>).value);\n }\n return Right.pure(new List(out));\n }\n if (eff === Option) {\n const out: unknown[] = [];\n for (const item of this._items) {\n const r = f(item);\n if (r instanceof Some) out.push((r as Some<unknown>).value);\n else return None.Instance;\n }\n return Some.pure(new List(out) as NonNullable<List<unknown>>);\n }\n if (eff === Promise) {\n return Promise.all(this._items.map(f as (a: A) => Promise<unknown>)).then((arr) => new List(arr));\n }\n throw new Error(`List.traverse: unknown effect type — expected IO, Either, Option, or Promise, got ${String(eff)}`);\n }\n\n /**\n * Returns a string representation of the `List`.\n *\n * @returns {string} A string showing all elements.\n *\n * @example\n * List.of(1, 2, 3).toString(); // \"[1, 2, 3]\"\n * List.empty<number>().toString(); // \"[]\"\n */\n public toString(): string {\n return `[${this._items.join(\", \")}]`;\n }\n}\n","import { IO } from \"./io\";\n\n/**\n * Represents a scheduling policy with configurable retries, delay factor, initial delay, and optional timeout.\n */\nexport interface Policy {\n /**\n * The maximum number of retry attempts. Must be a positive integer.\n */\n readonly recurs: number;\n\n /**\n * The factor by which the delay increases after each retry. Must be greater than or equal to 1.\n */\n readonly factor: number;\n\n /**\n * The initial delay in milliseconds before the first retry. Must be non-negative.\n */\n readonly delay: number;\n\n /**\n * Optional. The maximum duration in milliseconds that each attempt can take before timing out.\n * If not set, attempts will not time out.\n */\n readonly timeout?: number;\n\n /**\n * Optional. A randomization factor between 0 and 1.\n * If set, adds random jitter to the delay to prevent thundering herd problems.\n * For example, a factor of 0.1 adds up to +/- 10% variation to the delay.\n */\n readonly jitter?: number;\n}\n\n/**\n * Provides a default policy configuration.\n *\n * @param {number} recurs - The maximum number of retries.\n * @param {number} factor - The factor by which the delay increases after each retry.\n * @param {number} delay - The initial delay before the first retry, in milliseconds.\n * @param {number} [timeout] - The optional timeout for each attempt, in milliseconds.\n * @param {number} [jitter] - The randomization factor (0-1). Defaults to 0.\n * @returns {Policy} The default policy.\n */\nexport const defaultPolicy = (\n recurs: number = 3,\n factor: number = 1.2,\n delay: number = 1000,\n timeout?: number,\n jitter: number = 0\n): Policy => {\n return { recurs, factor, delay, timeout, jitter };\n};\n\n/**\n * Creates a delay promise that resolves after `ms` milliseconds, or rejects\n * immediately if the signal is already aborted or fires during the delay.\n */\nconst abortableDelay = <E>(ms: number, signal: AbortSignal, liftE: (error: unknown) => E): Promise<void> =>\n new Promise<void>((resolve, reject) => {\n if (signal.aborted) {\n reject(liftE(new CancellationError(\"Operation was cancelled\")));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n function onAbort() {\n clearTimeout(timeoutId);\n reject(liftE(new CancellationError(\"Operation was cancelled\")));\n }\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n/**\n * Represents a scheduling strategy for retrying asynchronous operations.\n *\n * Schedule integrates with IO's cancellation model through `AbortSignal`. When an IO\n * running a scheduled operation is cancelled (via `fiber.cancel()` or `IO.timeout`),\n * the signal propagates into the schedule's delay loops and aborts them immediately.\n *\n * The manual `cancel()` method is still supported for standalone usage outside IO.\n */\nexport class Schedule {\n private readonly policy: Policy;\n private readonly controller: AbortController = new AbortController();\n\n /**\n * Constructs a new Schedule instance.\n *\n * @param {Policy} policy - The scheduling policy to use for retries.\n */\n constructor(policy: Policy = defaultPolicy()) {\n if (policy.recurs !== Infinity && (!Number.isFinite(policy.recurs) || policy.recurs < 1)) {\n throw new PolicyValidationError(\"Policy validation error: 'recurs' must be a positive number >= 1 (or Infinity)\");\n }\n if (!Number.isFinite(policy.factor) || policy.factor < 1) {\n throw new PolicyValidationError(\"Policy validation error: 'factor' must be a finite number >= 1\");\n }\n if (!Number.isFinite(policy.delay) || policy.delay < 0) {\n throw new PolicyValidationError(\"Policy validation error: 'delay' must be a finite non-negative number\");\n }\n if (policy.timeout !== undefined && (!Number.isFinite(policy.timeout) || policy.timeout < 0)) {\n throw new PolicyValidationError(\"Policy validation error: 'timeout' must be a finite non-negative number\");\n }\n if (policy.jitter !== undefined && (!Number.isFinite(policy.jitter) || policy.jitter < 0 || policy.jitter > 1)) {\n throw new PolicyValidationError(\"Policy validation error: 'jitter' must be a finite number between 0 and 1\");\n }\n this.policy = policy;\n }\n\n /**\n * Wraps an IO operation with retry logic based on a defined policy and a specific condition.\n * The operation is retried with an increasing delay, which grows according to the policy factor.\n * If an operation exceeds the retry limit or fails due to other reasons, a RetryError is thrown.\n *\n * Cancellation is supported through two mechanisms:\n * - **IO signal**: When the IO running this schedule is cancelled (fiber, timeout), the AbortSignal\n * propagates and aborts any in-progress delay immediately.\n * - **Manual cancel()**: Calling `schedule.cancel()` aborts the internal controller, which has the\n * same effect.\n *\n * @template E The error type inside the IO.\n * @template A The potential result of the IO operation.\n *\n * @param {IO<E, A>} eff The operation to retry.\n * @param {(error: E) => boolean} condition The condition under which to retry the operation.\n * @param {(error: unknown) => E} liftE A function that lifts a caught (unknown) error into an instance of E.\n *\n * @returns {IO<E, A>} An IO instance that encapsulates the original operation's result if successful,\n * or encapsulates a RetryError if the retry limit is reached without success.\n */\n retryIf<E, A>(eff: IO<E, A>, condition: (error: E) => boolean, liftE: (error: unknown) => E): IO<E, A> {\n const policy = this.policy;\n const manualSignal = this.controller.signal;\n\n return IO.cancellable<E, A>(\n async (ioSignal: AbortSignal) => {\n const merged = new AbortController();\n const abortMerged = () => merged.abort();\n\n if (ioSignal.aborted || manualSignal.aborted) {\n throw liftE(new CancellationError(\"Operation was cancelled\"));\n }\n\n ioSignal.addEventListener(\"abort\", abortMerged, { once: true });\n manualSignal.addEventListener(\"abort\", abortMerged, { once: true });\n\n try {\n let attempt = 0;\n let delay = policy.delay;\n\n while (attempt < policy.recurs) {\n if (merged.signal.aborted) {\n throw liftE(new CancellationError(\"Operation was cancelled\"));\n }\n\n const result = await this.withTimeout(eff, liftE).unsafeRun();\n if (result.type === \"Ok\") {\n return result.value;\n }\n const error = result.error;\n\n let shouldRetry: boolean;\n try {\n shouldRetry = condition(error);\n } catch (conditionError) {\n throw liftE(\n new ConditionalRetryError(\n `Retry condition threw: ${conditionError instanceof Error ? conditionError.message : String(conditionError)}`\n )\n );\n }\n\n if (!shouldRetry) {\n throw liftE(new ConditionalRetryError(`Retry condition not met: ${error}`));\n }\n if (attempt >= policy.recurs - 1) {\n throw liftE(new RetryError(`Retry limit reached without success: ${error}`));\n }\n\n await abortableDelay(this.applyJitter(delay), merged.signal, liftE);\n\n delay *= policy.factor;\n attempt++;\n }\n throw liftE(new RetryError(\"Retry limit reached without success\"));\n } finally {\n ioSignal.removeEventListener(\"abort\", abortMerged);\n manualSignal.removeEventListener(\"abort\", abortMerged);\n }\n },\n (e: unknown) => (isLiftedError<E>(e) ? e : liftE(e instanceof Error ? e : new Error(String(e))))\n );\n }\n\n /**\n * Repeats the execution of an IO action based on a defined scheduling policy.\n * If the IO action succeeds, it is executed again until it either fails or the policy determines the execution should stop.\n *\n * Cancellation is supported through both the IO signal and `schedule.cancel()`.\n *\n * @template E The error type inside the IO.\n * @template A The potential result of the IO action.\n *\n * @param {IO<E, A>} eff The IO action to repeat.\n * @param {(error: unknown) => E} liftE A function that lifts a caught (unknown) error into an instance of E.\n *\n * @returns {IO<E, A>} An IO instance that encapsulates the last successful result\n * or a RepeatError if the action fails or exhausts the retries determined by the policy.\n */\n repeat<E, A>(eff: IO<E, A>, liftE: (error: unknown) => E): IO<E, A> {\n const policy = this.policy;\n const manualSignal = this.controller.signal;\n\n return IO.cancellable<E, A>(\n async (ioSignal: AbortSignal) => {\n const merged = new AbortController();\n const abortMerged = () => merged.abort();\n\n if (ioSignal.aborted || manualSignal.aborted) {\n throw liftE(new CancellationError(\"Operation was cancelled\"));\n }\n\n ioSignal.addEventListener(\"abort\", abortMerged, { once: true });\n manualSignal.addEventListener(\"abort\", abortMerged, { once: true });\n\n try {\n let hasResult = false;\n let lastSuccessResult: A | undefined;\n let delay = policy.delay;\n\n for (let attempt = 0; attempt < policy.recurs; attempt++) {\n if (merged.signal.aborted) {\n throw liftE(new CancellationError(\"Operation was cancelled\"));\n }\n\n const result = await this.withTimeout(eff, liftE).unsafeRun();\n\n if (result.type === \"Ok\") {\n hasResult = true;\n lastSuccessResult = result.value;\n\n if (attempt < policy.recurs - 1) {\n await abortableDelay(this.applyJitter(delay), merged.signal, liftE);\n delay *= policy.factor;\n }\n } else {\n throw liftE(new RepeatError(`Failed to execute repeat: ${result.error}`));\n }\n }\n\n if (hasResult) {\n return lastSuccessResult as A;\n }\n\n throw liftE(new RepeatError(\"The function provided never succeeded\"));\n } finally {\n ioSignal.removeEventListener(\"abort\", abortMerged);\n manualSignal.removeEventListener(\"abort\", abortMerged);\n }\n },\n (e: unknown) => (isLiftedError<E>(e) ? e : liftE(e instanceof Error ? e : new Error(String(e))))\n );\n }\n\n /**\n * Wraps an IO operation with an optional timeout configured by the scheduler policy.\n * If a valid timeout is provided and the operation exceeds this time,\n * it encapsulates a TimeoutError within the IO instance.\n *\n * @template E The error type inside the IO.\n * @template A The potential result of the IO operation.\n *\n * @param {IO<E, A>} eff The operation to wrap with the policy timeout.\n * @param {(error: unknown) => E} liftE A function that lifts a caught (unknown) error into an instance of E.\n *\n * @returns {IO<E, A>} An IO instance that either encapsulates the original operation's result\n * or a TimeoutError if the timeout is exceeded.\n */\n withTimeout<E, A>(eff: IO<E, A>, liftE: (error: unknown) => E): IO<E, A> {\n const timeout = this.policy.timeout;\n if (!timeout || timeout < 1) {\n return eff;\n }\n\n return IO.lift<E, A>(async () => {\n let timeoutId: NodeJS.Timeout | null = null;\n let settled = false;\n\n const timeoutP = new Promise<A>((_, reject) => {\n timeoutId = setTimeout(() => {\n if (settled) return;\n settled = true;\n reject(liftE(new TimeoutError(`The operation timed out after ${timeout} milliseconds`)));\n }, timeout);\n });\n\n const opP = eff.unsafeRun().then((result) => {\n if (settled) return result.type === \"Ok\" ? result.value : Promise.reject(result.error);\n settled = true;\n if (timeoutId) clearTimeout(timeoutId);\n switch (result.type) {\n case \"Ok\":\n return result.value;\n case \"Err\":\n return Promise.reject(result.error);\n }\n });\n\n try {\n return await Promise.race([opP, timeoutP]);\n } catch (error) {\n if (timeoutId) clearTimeout(timeoutId);\n return Promise.reject(error);\n }\n });\n }\n\n /**\n * Cancels the ongoing scheduled operation. Aborts any in-progress delay immediately.\n *\n * This works both when the schedule is used standalone and when it's running inside an IO.\n * For IO-managed schedules (via `retryIf` on IO), cancellation through `fiber.cancel()` or\n * `IO.timeout` is preferred — it automatically propagates through the AbortSignal.\n *\n * @example\n * const schedule = new Schedule();\n * const operation = schedule.retryIf(eff, () => true, e => e);\n *\n * setTimeout(() => schedule.cancel(), 150);\n * const result = await operation.unsafeRun();\n */\n cancel(): void {\n this.controller.abort();\n }\n\n private applyJitter(delay: number): number {\n if (!this.policy.jitter) return delay;\n const amount = delay * this.policy.jitter;\n const offset = (Math.random() * 2 - 1) * amount;\n return Math.max(0, delay + offset);\n }\n}\n\n/**\n * Type guard: returns true if the value was already lifted through `liftE` and should not be double-wrapped.\n * We detect this by checking if the value is NOT a plain Error subclass from this module.\n */\nconst isLiftedError = <E>(e: unknown): e is E =>\n !(\n e instanceof CancellationError ||\n e instanceof RetryError ||\n e instanceof RepeatError ||\n e instanceof ConditionalRetryError ||\n e instanceof TimeoutError ||\n e instanceof PolicyValidationError\n );\n\n/**\n * Represents an error related to invalid scheduling policy configurations.\n * @extends Error\n */\nexport class PolicyValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PolicyValidationError\";\n }\n}\n\n/**\n * Represents an error that occurs when an operation exceeds the allowed timeout limit.\n * @extends Error\n */\nexport class TimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TimeoutError\";\n }\n}\n\n/**\n * Represents an error that occurs when a retry condition is not met or the condition function itself throws.\n * @extends Error\n */\nexport class ConditionalRetryError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConditionalRetryError\";\n }\n}\n\n/**\n * Represents an error that occurs when the maximum number of retries is reached.\n * @extends Error\n */\nexport class RetryError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RetryError\";\n }\n}\n\n/**\n * Represents an error that occurs during the repetition of an operation.\n * @extends Error\n */\nexport class RepeatError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RepeatError\";\n }\n}\n\n/**\n * Represents an error that occurs when an operation is cancelled.\n * @extends Error\n */\nexport class CancellationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CancellationError\";\n }\n}\n","import { Either, Left, Right } from \"./either\";\nimport { List } from \"./list\";\nimport { NonEmptyList } from \"./non-empty-list\";\n// Circular dependency: schedule.ts imports IO from this module.\n// Safe because both modules only reference each other's exports at runtime (inside methods),\n// never at import/evaluation time. Do not add top-level code that uses Schedule eagerly.\nimport { defaultPolicy, Policy, Schedule } from \"./schedule\";\n\nexport interface Ok<A> {\n readonly type: \"Ok\";\n readonly value: A;\n}\n\nexport interface Err<E> {\n readonly type: \"Err\";\n readonly error: E;\n}\n\nexport interface Cancelled {\n readonly type: \"Cancelled\";\n}\n\nexport interface Fiber<E, A> {\n /** Wait for the computation to complete. */\n readonly join: () => Promise<Ok<A> | Err<E> | Cancelled>;\n /** Request cancellation. Idempotent. Resolves after finalizers run. */\n readonly cancel: () => Promise<void>;\n /** The underlying AbortSignal for interop with platform APIs. */\n readonly signal: AbortSignal;\n}\n\ntype Node<E, A> =\n | { tag: \"Pure\"; value: A }\n | { tag: \"Fail\"; error: E }\n | { tag: \"Lift\"; run: (signal?: AbortSignal) => A | Promise<A>; liftE?: (e: unknown) => E }\n | { tag: \"Map\"; io: Node<any, any>; f: (a: any) => A }\n | { tag: \"FlatMap\"; io: Node<any, any>; f: (a: any) => IO<any, A> }\n | { tag: \"MapErr\"; io: Node<any, any>; f: (e: any) => E }\n | { tag: \"FlatMapErr\"; io: Node<any, any>; f: (e: any) => IO<E, A> }\n | { tag: \"Tap\"; io: Node<E, A>; f: (a: any) => void | Promise<void> }\n | { tag: \"TapErr\"; io: Node<E, A>; f: (e: any) => void | Promise<void> }\n | { tag: \"Ensure\"; io: Node<E, A>; predicate: (a: any) => boolean; liftE: (a: any) => E }\n | { tag: \"FoldM\"; io: Node<any, any>; onOk: (a: any) => IO<E, A>; onErr: (e: any) => IO<E, A> }\n | { tag: \"OnCancel\"; io: Node<E, A>; finalizer: () => void | Promise<void> };\n\ntype Frame =\n | { tag: \"Map\"; f: (a: any) => any }\n | { tag: \"FlatMap\"; f: (a: any) => IO<any, any> }\n | { tag: \"MapErr\"; f: (e: any) => any }\n | { tag: \"FlatMapErr\"; f: (e: any) => IO<any, any> }\n | { tag: \"Tap\"; f: (a: any) => void | Promise<void> }\n | { tag: \"TapErr\"; f: (e: any) => void | Promise<void> }\n | { tag: \"FoldM\"; onOk: (a: any) => IO<any, any>; onErr: (e: any) => IO<any, any> }\n | { tag: \"Ensure\"; predicate: (a: any) => boolean; liftE: (a: any) => any }\n | { tag: \"OnCancel\"; finalizer: () => void | Promise<void> };\n\n/** Module-private key for IO's ADT node. Not exported — external code cannot access it. */\nconst NODE = Symbol(\"IO.node\");\n\n/** Module-private sentinel tag for typed error escape in Do/parMapN/race. */\nconst IO_ESCAPE = Symbol(\"IO.escape\");\n\ninterface IOEscape<E> {\n readonly [IO_ESCAPE]: true;\n readonly error: E;\n}\n\nfunction ioEscape<E>(error: E): IOEscape<E> {\n return { [IO_ESCAPE]: true, error };\n}\n\nfunction isIOEscape(e: unknown): e is IOEscape<any> {\n return e != null && typeof e === \"object\" && IO_ESCAPE in (e as object);\n}\n\n/** Module-private sentinel for cancellation propagation through Lift boundaries. */\nconst IO_CANCELLED = Symbol(\"IO.cancelled\");\n\ninterface IOCancelled {\n readonly [IO_CANCELLED]: true;\n}\n\nfunction ioCancelled(): never {\n throw { [IO_CANCELLED]: true } as IOCancelled;\n}\n\nfunction isIOCancelled(e: unknown): e is IOCancelled {\n return e != null && typeof e === \"object\" && IO_CANCELLED in (e as object);\n}\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return value != null && typeof (value as any).then === \"function\";\n}\n\nasync function interpret<E, A>(root: Node<E, A>, signal?: AbortSignal): Promise<Ok<A> | Err<E> | Cancelled> {\n const stack: Frame[] = [];\n let cur: Node<any, any> = root;\n\n while (true) {\n if (signal?.aborted) {\n const finalizers: Array<() => void | Promise<void>> = [];\n while (stack.length > 0) {\n const frame = stack.pop()!;\n if (frame.tag === \"OnCancel\") {\n finalizers.push(frame.finalizer);\n }\n }\n for (const fin of finalizers) {\n try {\n const r = fin();\n if (isThenable(r)) await r;\n } catch {\n /* swallow */\n }\n }\n return { type: \"Cancelled\" };\n }\n\n switch (cur.tag) {\n case \"Map\":\n stack.push({ tag: \"Map\", f: cur.f });\n cur = cur.io;\n break;\n case \"FlatMap\":\n stack.push({ tag: \"FlatMap\", f: cur.f });\n cur = cur.io;\n break;\n case \"MapErr\":\n stack.push({ tag: \"MapErr\", f: cur.f });\n cur = cur.io;\n break;\n case \"FlatMapErr\":\n stack.push({ tag: \"FlatMapErr\", f: cur.f });\n cur = cur.io;\n break;\n case \"Tap\":\n stack.push({ tag: \"Tap\", f: cur.f });\n cur = cur.io;\n break;\n case \"TapErr\":\n stack.push({ tag: \"TapErr\", f: cur.f });\n cur = cur.io;\n break;\n case \"FoldM\":\n stack.push({ tag: \"FoldM\", onOk: cur.onOk, onErr: cur.onErr });\n cur = cur.io;\n break;\n case \"Ensure\":\n stack.push({ tag: \"Ensure\", predicate: cur.predicate, liftE: cur.liftE });\n cur = cur.io;\n break;\n case \"OnCancel\":\n stack.push({ tag: \"OnCancel\", finalizer: cur.finalizer });\n cur = cur.io;\n break;\n\n case \"Lift\": {\n const { run, liftE } = cur;\n try {\n const result = run(signal);\n const value = isThenable(result) ? await result : result;\n cur = { tag: \"Pure\", value };\n } catch (e) {\n if (isIOCancelled(e)) {\n cur = { tag: \"Pure\", value: undefined };\n break;\n }\n cur = { tag: \"Fail\", error: liftE ? liftE(e) : e };\n }\n break;\n }\n\n case \"Pure\": {\n if (stack.length === 0) return { type: \"Ok\", value: cur.value };\n\n const frame = stack.pop()!;\n switch (frame.tag) {\n case \"Map\":\n try {\n cur = { tag: \"Pure\", value: frame.f(cur.value) };\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n case \"FlatMap\":\n try {\n cur = frame.f(cur.value)[NODE];\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n case \"Tap\":\n try {\n const r = frame.f(cur.value);\n if (isThenable(r)) await r;\n } catch {\n /* preserve original value */\n }\n break;\n case \"Ensure\": {\n const val = cur.value;\n try {\n if (!frame.predicate(val)) {\n cur = { tag: \"Fail\", error: frame.liftE(val) };\n }\n } catch {\n cur = { tag: \"Fail\", error: frame.liftE(val) };\n }\n break;\n }\n case \"FoldM\":\n try {\n cur = frame.onOk(cur.value)[NODE];\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n case \"MapErr\":\n case \"FlatMapErr\":\n case \"TapErr\":\n case \"OnCancel\":\n break;\n }\n break;\n }\n\n case \"Fail\": {\n if (stack.length === 0) return { type: \"Err\", error: cur.error };\n\n const frame = stack.pop()!;\n switch (frame.tag) {\n case \"MapErr\":\n try {\n cur = { tag: \"Fail\", error: frame.f(cur.error) };\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n case \"FlatMapErr\":\n try {\n cur = frame.f(cur.error)[NODE];\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n case \"TapErr\":\n try {\n const r = frame.f(cur.error);\n if (isThenable(r)) await r;\n } catch {\n /* preserve original error */\n }\n break;\n case \"FoldM\":\n try {\n cur = frame.onErr(cur.error)[NODE];\n } catch (e) {\n cur = { tag: \"Fail\", error: e };\n }\n break;\n case \"Map\":\n case \"FlatMap\":\n case \"Tap\":\n case \"Ensure\":\n case \"OnCancel\":\n break;\n }\n break;\n }\n }\n }\n}\n\n/**\n * `IO<E, A>` represents a lazy, composable description of an effectful computation\n * that may succeed with a value of type `A` or fail with an error of type `E`.\n *\n * Computations are described as an immutable ADT tree and only executed when\n * `unsafeRun()` is called. The interpreter uses an explicit stack (trampoline)\n * to evaluate the tree, ensuring stack safety for arbitrarily deep chains.\n */\nexport class IO<E, A> {\n /** @internal Keyed by module-private Symbol — inaccessible to external code. */\n readonly [NODE]: Node<E, A>;\n\n /** @internal */\n private constructor(node: Node<E, A>) {\n this[NODE] = node;\n }\n\n /**\n * @internal Type-erased constructor for combinators that change E or A.\n * Use `new IO(...)` when the return type matches `IO<E, A>` (same types).\n * Use `IO.wrap(...)` when the combinator changes E or A (e.g. map, flatMap, mapErr, foldM).\n */\n private static wrap<E, A>(node: Node<any, any>): IO<E, A> {\n return new IO<E, A>(node as Node<E, A>);\n }\n\n /**\n * Creates an IO from an effectful function that may be synchronous or asynchronous.\n * The function is not executed until `unsafeRun()` is called on the resulting IO,\n * preserving laziness. The interpreter detects whether the return value is a\n * Promise at runtime and awaits only when necessary.\n *\n * If the function throws (or the returned Promise rejects), the error is captured\n * as the `Err` channel. When `liftE` is provided, caught exceptions are transformed\n * into the error type `E` before being placed in the error channel.\n *\n * @template E The error type.\n * @template A The success type.\n * @param {() => A | Promise<A>} f The effectful function to defer.\n * @param {(e: unknown) => E} [liftE] Optional function to transform caught exceptions into the error type E.\n * @returns {IO<E, A>} A new IO that, when executed, will run the function and capture its result.\n *\n * @example\n * // Synchronous effect\n * const syncIO = IO.lift(() => 42);\n *\n * // Asynchronous effect\n * const asyncIO = IO.lift(() => fetch('/api/data').then(r => r.json()));\n *\n * // With error transformation\n * const typedIO = IO.lift(\n * () => riskyOperation(),\n * (e) => new AppError(String(e))\n * );\n */\n static lift<E, A>(f: (signal?: AbortSignal) => A | Promise<A>, liftE?: (e: unknown) => E): IO<E, A> {\n return new IO({ tag: \"Lift\", run: f, liftE });\n }\n\n /**\n * Creates an IO from a function that receives an `AbortSignal` for cooperative cancellation.\n * Use this when the underlying operation supports cancellation (e.g., `fetch`, streams, timers).\n *\n * The signal is provided by the interpreter when the IO is forked. If the IO is run\n * without forking (via `unsafeRun`), the signal is never aborted.\n *\n * @template E The error type.\n * @template A The success type.\n * @param {(signal: AbortSignal) => A | Promise<A>} f The cancellable effectful function.\n * @param {(e: unknown) => E} [liftE] Optional function to transform caught exceptions into E.\n * @returns {IO<E, A>} A new IO that cooperates with cancellation.\n *\n * @example\n * const io = IO.cancellable<AppError, Response>(\n * (signal) => fetch('/api/data', { signal }),\n * (e) => new AppError(String(e))\n * );\n */\n static cancellable<E, A>(f: (signal: AbortSignal) => A | Promise<A>, liftE?: (e: unknown) => E): IO<E, A> {\n return new IO({ tag: \"Lift\", run: (signal?: AbortSignal) => f(signal ?? new AbortController().signal), liftE });\n }\n\n /**\n * Guarantees resource cleanup by structuring effectful code into three phases:\n * **acquire**, **use**, and **release**. The release action is *always* executed,\n * regardless of whether `use` succeeds, fails, or is cancelled.\n *\n * This is the classic functional `bracket` pattern (Cats `bracket`, Haskell `bracket`,\n * ZIO `acquireRelease`). It eliminates resource leaks by construction — the type\n * system ensures that every acquired resource has a corresponding release.\n *\n * Semantics:\n * - If **acquire** fails or is cancelled, `use` and `release` are never called.\n * - If **use** succeeds, `release` runs and the success value is returned.\n * - If **use** fails, `release` runs and the original error is returned.\n * - If **use** is cancelled, `release` runs and `Cancelled` is propagated.\n * - **release** runs without an `AbortSignal` — it always runs to completion.\n * - If `release` itself fails, the error is swallowed and `use`'s result takes priority\n * (following Cats Effect semantics).\n *\n * @template E The error type shared by acquire and use.\n * @template R The resource type produced by acquire.\n * @template A The success type produced by use.\n * @param {IO<E, R>} acquire An IO that acquires the resource.\n * @param {(r: R) => IO<E, A>} use A function that uses the resource and produces a result.\n * @param {(r: R) => IO<never, void>} release A function that releases the resource. Must not fail.\n * @returns {IO<E, A>} An IO that acquires, uses, and releases the resource.\n *\n * @example\n * // Database connection with guaranteed cleanup\n * const io = IO.bracket(\n * IO.lift(() => openConnection()),\n * (conn) => IO.lift(() => conn.query('SELECT * FROM users')),\n * (conn) => IO.lift(() => conn.close())\n * );\n *\n * @example\n * // File handle with guaranteed close\n * const io = IO.bracket(\n * IO.lift(() => fs.open('/tmp/data.txt', 'r')),\n * (fd) => IO.lift(() => fs.read(fd, buffer, 0, 1024, 0)),\n * (fd) => IO.lift(() => fs.close(fd))\n * );\n *\n * @example\n * // Composable with other IO combinators\n * const io = IO.bracket(\n * acquirePool(),\n * (pool) => queryUsers(pool).map(users => users.filter(u => u.active)),\n * (pool) => IO.lift(() => pool.shutdown())\n * ).mapErr(e => new AppError(e));\n */\n static bracket<E, R, A>(acquire: IO<E, R>, use: (r: R) => IO<E, A>, release: (r: R) => IO<never, void>): IO<E, A> {\n return IO.lift<E, A>(\n async (signal?: AbortSignal) => {\n const acqResult = await interpret(acquire[NODE], signal);\n if (acqResult.type === \"Cancelled\") ioCancelled();\n if (acqResult.type === \"Err\") throw ioEscape(acqResult.error);\n\n const resource = acqResult.value;\n\n let useResult: Ok<A> | Err<E> | Cancelled;\n try {\n useResult = await interpret(use(resource)[NODE], signal);\n } catch (e) {\n await interpret(release(resource)[NODE]).catch(() => {});\n throw e;\n }\n\n await interpret(release(resource)[NODE]).catch(() => {});\n\n if (useResult.type === \"Cancelled\") ioCancelled();\n if (useResult.type === \"Err\") throw ioEscape(useResult.error);\n return useResult.value;\n },\n (e: unknown) => {\n if (isIOCancelled(e)) throw e;\n if (isIOEscape(e)) return e.error as E;\n return e as E;\n }\n );\n }\n\n /**\n * Lifts an already-computed value into IO with no side effect.\n * The value is available immediately — no deferred computation takes place.\n *\n * This is useful for wrapping a known value in the IO type so it can be composed\n * with other IO operations via `flatMap`, `map`, etc.\n *\n * @template A The type of the value.\n * @param {A} a The value to wrap.\n * @returns {IO<never, A>} An IO that immediately succeeds with the given value.\n *\n * @example\n * const io = IO.pure(42);\n * const result = await io.unsafeRun(); // { type: \"Ok\", value: 42 }\n */\n static pure<A>(a: A): IO<never, A> {\n return new IO({ tag: \"Pure\", value: a });\n }\n\n /**\n * Creates an IO that fails immediately with the given error.\n * No computation is performed — the error is placed directly in the error channel.\n *\n * @template E The error type.\n * @template A The success type (defaults to `never` since this IO never succeeds).\n * @param {E} error The error value.\n * @returns {IO<E, A>} An IO that immediately fails with the given error.\n *\n * @example\n * const io = IO.fail(new Error(\"something went wrong\"));\n * const result = await io.unsafeRun(); // { type: \"Err\", error: Error(\"something went wrong\") }\n */\n static fail<E, A = never>(error: E): IO<E, A> {\n return new IO({ tag: \"Fail\", error });\n }\n\n /**\n * An IO that succeeds with `void`. Useful as a no-op placeholder\n * or as the terminal value in a chain of side-effecting operations.\n *\n * @example\n * const io = IO.unit;\n * const result = await io.unsafeRun(); // { type: \"Ok\", value: undefined }\n */\n static readonly unit: IO<never, void> = new IO<never, void>({\n tag: \"Pure\",\n value: undefined as unknown as void,\n });\n\n /**\n * Creates an Ok result value. Convenience constructor for building result values\n * outside of the IO execution context.\n *\n * @template A The type of the success value.\n * @param {A} value The success value.\n * @returns {Ok<A>} A result representing success.\n */\n static ok<A>(value: A): Ok<A> {\n return { type: \"Ok\", value };\n }\n\n /**\n * Creates an Err result value. Convenience constructor for building result values\n * outside of the IO execution context.\n *\n * @template E The type of the error value.\n * @param {E} error The error value.\n * @returns {Err<E>} A result representing failure.\n */\n static err<E>(error: E): Err<E> {\n return { type: \"Err\", error };\n }\n\n /**\n * Transforms the success value of this IO using the provided function.\n * If this IO fails, the function is not called and the error propagates unchanged.\n *\n * This is an O(1) operation — it wraps the current computation in a new node\n * without executing anything.\n *\n * @template B The type of the transformed value.\n * @param {(a: A) => B} f The transformation function.\n * @returns {IO<E, B>} A new IO representing the transformed computation.\n *\n * @example\n * const io = IO.lift(() => 21).map(n => n * 2);\n * const result = await io.unsafeRun(); // { type: \"Ok\", value: 42 }\n */\n map<B>(f: (a: A) => B): IO<E, B> {\n return IO.wrap({ tag: \"Map\", io: this[NODE], f });\n }\n\n /**\n * Chains a dependent IO computation on the success value.\n * If this IO fails, the function is not called and the error propagates unchanged.\n *\n * This is the monadic `bind` operation, enabling sequential composition of IO\n * operations where each step may depend on the result of the previous one.\n *\n * @template B The type of the value produced by the chained computation.\n * @param {(a: A) => IO<E, B>} f A function that takes the success value and returns a new IO.\n * @returns {IO<E, B>} A new IO representing the composed computation.\n *\n * @example\n * const io = IO.lift(() => 1).flatMap(n => IO.lift(() => n + 1));\n * const result = await io.unsafeRun(); // { type: \"Ok\", value: 2 }\n */\n flatMap<B>(f: (a: A) => IO<E, B>): IO<E, B> {\n return IO.wrap({ tag: \"FlatMap\", io: this[NODE], f });\n }\n\n /**\n * Transforms the error value of this IO using the provided function.\n * If this IO succeeds, the function is not called and the value propagates unchanged.\n *\n * Useful for converting raw exceptions or generic errors into typed domain errors.\n *\n * @template F The type of the transformed error.\n * @param {(e: E) => F} f The error transformation function.\n * @returns {IO<F, A>} A new IO with the transformed error type.\n *\n * @example\n * const io = IO.lift(() => { throw new Error(\"boom\"); })\n * .mapErr(e => new AppError(e.message));\n */\n mapErr<F>(f: (e: E) => F): IO<F, A> {\n return IO.wrap({ tag: \"MapErr\", io: this[NODE], f });\n }\n\n /**\n * Transforms both the error and success channels simultaneously.\n * This is the Bifunctor `bimap` operation.\n *\n * @template F The transformed error type.\n * @template B The transformed success type.\n * @param {(e: E) => F} fe The error transformation function.\n * @param {(a: A) => B} fa The success transformation function.\n * @returns {IO<F, B>} A new IO with both channels transformed.\n *\n * @example\n * const io = IO.lift(() => 42)\n * .bimap(\n * err => `Error: ${err}`,\n * val => val * 2\n * );\n */\n bimap<F, B>(fe: (e: E) => F, fa: (a: A) => B): IO<F, B> {\n return this.map(fa).mapErr(fe);\n }\n\n /**\n * Chains a dependent IO computation on the error value.\n * If this IO succeeds, the function is not called and the value propagates unchanged.\n * If this IO fails, the function receives the error and returns a new IO\n * that replaces the failed computation.\n *\n * This is the error-channel counterpart to `flatMap`. Recovery may change the error type:\n * because a successful recovery discharges the original `E`, the only way the result can\n * still fail is the recovery's own error type `F` — so the result is `IO<F, A>`, not\n * `IO<E | F, A>`. This mirrors ZIO's `catchAll`. For single-type recovery, `F` infers to `E`\n * and the signature is unchanged.\n *\n * @template F The error type of the recovery IO (defaults to `E` by inference).\n * @param {(error: E) => IO<F, A>} f A function that takes the error and returns a new IO.\n * @returns {IO<F, A>} A new IO that either succeeds normally or recovers into error type `F`.\n *\n * @example\n * // Recovery that changes the error type: HttpError → DomainError\n * const io: IO<DomainError, User> = fetchUser()\n * .flatMapErr(httpErr => refreshTokenThen(httpErr).mapErr(toDomainError));\n */\n flatMapErr<F>(f: (error: E) => IO<F, A>): IO<F, A> {\n return IO.wrap({ tag: \"FlatMapErr\", io: this[NODE], f }) as unknown as IO<F, A>;\n }\n\n /**\n * Executes a side-effect on the success value without changing the result.\n * If this IO fails, the function is not called. The callback may be synchronous\n * or asynchronous — the interpreter awaits if it returns a Promise.\n *\n * If the side-effect throws, the exception is swallowed and the original success\n * value is preserved. Use `map` or `flatMap` if failure should propagate.\n *\n * @param {(a: A) => void | Promise<void>} f The side-effect function.\n * @returns {IO<E, A>} A new IO that performs the side-effect but preserves the original result.\n *\n * @example\n * const io = IO.lift(() => 42).tap(value => console.log(\"Got:\", value));\n */\n tap(f: (a: A) => void | Promise<void>): IO<E, A> {\n return IO.wrap({ tag: \"Tap\", io: this[NODE], f });\n }\n\n /**\n * Executes a side-effect on the error value without changing the result.\n * If this IO succeeds, the function is not called. The callback may be synchronous\n * or asynchronous — the interpreter awaits if it returns a Promise.\n *\n * If the side-effect throws, the exception is swallowed and the original error\n * is preserved. Use `mapErr` or `flatMapErr` if failure should propagate.\n *\n * @param {(e: E) => void | Promise<void>} f The side-effect function.\n * @returns {IO<E, A>} A new IO that performs the side-effect but preserves the original error.\n *\n * @example\n * const io = IO.fail(new Error(\"boom\")).tapErr(e => logger.error(e));\n */\n tapErr(f: (e: E) => void | Promise<void>): IO<E, A> {\n return IO.wrap({ tag: \"TapErr\", io: this[NODE], f });\n }\n\n /**\n * Validates the success value against a predicate (Cats `ensure`).\n * If the predicate returns `false`, the success is converted into an error\n * using the `liftE` function. If this IO already fails, the predicate is not checked.\n *\n * @param {(a: A) => boolean} predicate The validation function.\n * @param {(a: A) => E} liftE Converts the value into an error when the predicate fails.\n * @returns {IO<E, A>} A new IO that validates the result.\n *\n * @example\n * const io = IO.lift(() => fetchAge())\n * .ensure(age => age >= 18, age => `Must be 18+, got ${age}`);\n */\n ensure(predicate: (a: A) => boolean, liftE: (a: A) => E): IO<E, A> {\n return IO.wrap({ tag: \"Ensure\", io: this[NODE], predicate, liftE });\n }\n\n /**\n * Registers a cleanup action that runs only if this IO is cancelled.\n * If the IO completes normally (Ok or Err), the finalizer is never called.\n * Finalizers run in LIFO order (innermost first) during cancellation unwinding.\n *\n * @param {() => void | Promise<void>} finalizer The cleanup function.\n * @returns {IO<E, A>} A new IO with the finalizer registered.\n *\n * @example\n * const io = IO.cancellable((signal) => fetch('/api', { signal }))\n * .onCancel(() => console.log(\"Request was cancelled\"));\n */\n onCancel(finalizer: () => void | Promise<void>): IO<E, A> {\n return IO.wrap({ tag: \"OnCancel\", io: this[NODE], finalizer });\n }\n\n /**\n * Monadic fold — branches on both success and error channels, where each arm\n * returns a new IO. Unlike `fold` (which is terminal and returns a plain value),\n * `foldM` produces a composable IO that can be further chained.\n *\n * @template F The error type of the resulting IO.\n * @template B The success type of the resulting IO.\n * @param {(e: E) => IO<F, B>} onErr Handler for the error case.\n * @param {(a: A) => IO<F, B>} onOk Handler for the success case.\n * @returns {IO<F, B>} A new IO representing the branched computation.\n *\n * @example\n * const io = IO.lift(() => riskyOp()).foldM(\n * err => IO.fail(`Recovered: ${err}`),\n * val => IO.pure(val * 2)\n * );\n */\n foldM<F, B>(onErr: (e: E) => IO<F, B>, onOk: (a: A) => IO<F, B>): IO<F, B> {\n return IO.wrap({ tag: \"FoldM\", io: this[NODE], onOk, onErr });\n }\n\n /**\n * Reifies the error channel into the success channel. After `attempt`, the\n * resulting IO cannot fail — its value describes either success or failure\n * as an `Either`. Equivalent to Cats' `attempt` / ZIO's `either`.\n *\n * Unlike `flatMapErr`, which recovers with a replacement IO, `attempt` makes\n * both outcomes observable as values, allowing callers to inspect the error\n * while staying in a non-failing IO.\n *\n * @returns {IO<never, Either<E, A>>} A non-failing IO whose value is `Left(e)` on failure or `Right(a)` on success.\n *\n * @example\n * const io: IO<ApiError, User> = UserService.get(id);\n * const safe = await io.attempt().unsafeRun();\n * // safe: { type: \"Ok\", value: Left(err) } on failure,\n * // { type: \"Ok\", value: Right(user) } on success\n */\n attempt(): IO<never, Either<E, A>> {\n return this.foldM<never, Either<E, A>>(\n (e) => IO.pure(Left.pure(e)),\n (a) => IO.pure(Right.pure(a))\n );\n }\n\n /**\n * Discards both success and failure. The resulting IO runs purely for its\n * side effects and can never fail. Equivalent to ZIO's `ignore`, or Cats'\n * `attempt.void`.\n *\n * Useful for \"best-effort\" fan-out patterns where each branch taps its\n * outcome but must not abort siblings on failure — e.g. parallel tile loads\n * on a dashboard where a missing endpoint should skip that tile without\n * failing the whole fetch.\n *\n * @returns {IO<never, void>} A non-failing IO producing `undefined`.\n *\n * @example\n * await IO.parMapN(\n * UserService.prefetch(id).tap(cache.set).ignore(),\n * SessionService.touch().ignore(),\n * () => undefined,\n * ).unsafeRun();\n */\n ignore(): IO<never, void> {\n return this.foldM<never, void>(\n () => IO.unit,\n () => IO.unit\n );\n }\n\n /**\n * Executes the computation described by this IO and returns the result.\n * The interpreter walks the ADT tree using an explicit stack (trampoline),\n * ensuring stack safety for arbitrarily deep chains.\n *\n * @returns {Promise<Err<E> | Ok<A>>} The result of the computation.\n *\n * @example\n * const result = await IO.lift(() => 42).unsafeRun();\n * // result: { type: \"Ok\", value: 42 }\n */\n async unsafeRun(): Promise<Err<E> | Ok<A>> {\n return interpret(this[NODE]) as Promise<Ok<A> | Err<E>>;\n }\n\n /**\n * Executes the IO and folds both outcomes (success and error) into a single type.\n * This is a terminal operation — it runs the computation and returns a plain value.\n *\n * @template B The result type after folding.\n * @param {(e: E) => B} onErr Handler for the error case.\n * @param {(a: A) => B} onOk Handler for the success case.\n * @returns {Promise<B>} The folded result.\n *\n * @example\n * const message = await IO.lift(() => 42).fold(\n * err => `Failed: ${err}`,\n * val => `Got: ${val}`\n * );\n * // message: \"Got: 42\"\n */\n async fold<B>(onErr: (e: E) => B, onOk: (a: A) => B): Promise<B> {\n const result = await this.unsafeRun();\n return result.type === \"Ok\" ? onOk(result.value) : onErr(result.error);\n }\n\n /**\n * Executes the IO and returns the success value, or `null` if the computation fails.\n *\n * Note: if `A` itself can be `null`, the return value is ambiguous — a `null` result\n * could mean either \"succeeded with null\" or \"failed.\" Use `unsafeRun()` or `fold`\n * when the distinction matters.\n *\n * @returns {Promise<A | null>} The success value or null.\n *\n * @example\n * const value = await IO.lift(() => 42).getOrNull(); // 42\n * const nope = await IO.fail(\"err\").getOrNull(); // null\n */\n async getOrNull(): Promise<A | null> {\n const result = await this.unsafeRun();\n return result.type === \"Ok\" ? result.value : null;\n }\n\n /**\n * Executes the IO and returns the success value, or evaluates the provided\n * default function on error. The default is lazy to avoid unnecessary computation.\n *\n * @param {() => A} defaultValue A function that produces the fallback value.\n * @returns {Promise<A>} The success value or the default.\n *\n * @example\n * const value = await IO.fail(\"err\").getOrElse(() => 0); // 0\n */\n async getOrElse(defaultValue: () => A): Promise<A> {\n const result = await this.unsafeRun();\n return result.type === \"Ok\" ? result.value : defaultValue();\n }\n\n /**\n * Executes the IO and returns the success value, or applies the handler\n * function to the error to produce a fallback value.\n *\n * @param {(error: E) => A} handler A function that transforms the error into a success value.\n * @returns {Promise<A>} The success value or the handled error.\n *\n * @example\n * const value = await IO.fail(new Error(\"boom\"))\n * .getOrHandleErr(e => `Handled: ${e.message}`);\n * // value: \"Handled: boom\"\n */\n async getOrHandleErr(handler: (error: E) => A): Promise<A> {\n const result = await this.unsafeRun();\n return result.type === \"Ok\" ? result.value : handler(result.error);\n }\n\n /**\n * Retries this IO when the condition is met, using the given scheduling policy.\n * The operation is retried with increasing delay based on the policy's factor and jitter settings.\n *\n * If the operation exceeds the retry limit, a `RetryError` is thrown.\n * If the condition is not met, a `ConditionalRetryError` is thrown.\n * Both are transformed through `liftE` into the error type `E`.\n *\n * @param {(error: E) => boolean} condition Predicate on the error — retry only when this returns true.\n * @param {(error: Error) => E} liftE Transforms schedule errors (e.g. RetryError, TimeoutError) into E.\n * @param {Policy} [policy] Scheduling policy (defaults to 3 retries, 1.2x backoff, 1s delay).\n * @returns {IO<E, A>} A new IO that wraps the retry logic.\n *\n * @example\n * const io = IO.lift(() => fetchData())\n * .retryIf(\n * err => err instanceof NetworkError,\n * e => new AppError(e instanceof Error ? e.message : String(e)),\n * { recurs: 5, delay: 1000, factor: 2 }\n * );\n */\n retryIf(condition: (error: E) => boolean, liftE: (error: unknown) => E, policy: Policy = defaultPolicy()): IO<E, A> {\n return IO.lift<E, Schedule>(\n () => new Schedule(policy),\n (e: unknown) => liftE(e instanceof Error ? e : new Error(String(e)))\n ).flatMap((scheduler) => scheduler.retryIf(this, condition, liftE));\n }\n\n /**\n * Applies a timeout to this IO. If the computation does not complete within `ms`\n * milliseconds, it is cancelled and the error produced by `onTimeout` is returned\n * in the error channel. If the computation completes before the deadline, the\n * timeout timer is cleared and the result is returned normally.\n *\n * The timeout error type `F` is unioned with the original error type `E`,\n * so the caller must handle both. The underlying computation is cooperatively\n * cancelled via `AbortSignal` when the timeout fires.\n *\n * This is a first-class replacement for the verbose `IO.race` workaround:\n * ```typescript\n * // Before — manual race\n * IO.race(\n * operation,\n * IO.lift(async () => { await delay(5000); throw new TimeoutError(); })\n * )\n *\n * // After — first-class combinator\n * operation.timeout(5000, () => new TimeoutError('Exceeded 5s'))\n * ```\n *\n * @template F The timeout error type.\n * @param {number} ms The timeout duration in milliseconds.\n * @param {() => F} onTimeout A thunk that produces the timeout error value.\n * @returns {IO<E | F, A>} A new IO that fails with `F` if the timeout elapses.\n *\n * @example\n * const io = IO.lift(() => fetch('/api/slow'))\n * .timeout(5000, () => new TimeoutError('Request exceeded 5s'));\n *\n * @example\n * // Composable with mapErr to unify error types\n * const io = fetchUser(id)\n * .timeout(3000, () => ({ code: 'TIMEOUT', message: 'User fetch timed out' }))\n * .mapErr(e => normalizeError(e));\n */\n timeout<F>(ms: number, onTimeout: () => F): IO<E | F, A> {\n const node = this[NODE];\n return IO.lift<E | F, A>(\n (signal?: AbortSignal) => {\n return new Promise<A>((resolve, reject) => {\n const controller = new AbortController();\n\n let unlinkParent: (() => void) | undefined;\n if (signal) {\n if (signal.aborted) {\n controller.abort();\n } else {\n const onAbort = () => controller.abort();\n signal.addEventListener(\"abort\", onAbort, { once: true });\n unlinkParent = () => signal.removeEventListener(\"abort\", onAbort);\n }\n }\n\n let settled = false;\n const settle = () => {\n settled = true;\n if (unlinkParent) unlinkParent();\n };\n\n const timer = setTimeout(() => {\n if (settled) return;\n settle();\n controller.abort();\n reject(ioEscape(onTimeout()));\n }, ms);\n\n interpret(node, controller.signal).then((result) => {\n if (settled) return;\n settle();\n clearTimeout(timer);\n if (result.type === \"Ok\") resolve(result.value);\n else if (result.type === \"Cancelled\") reject({ [IO_CANCELLED]: true });\n else reject(ioEscape(result.error));\n });\n\n controller.signal.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n },\n { once: true }\n );\n });\n },\n (e: unknown) => {\n if (isIOCancelled(e)) throw e;\n if (isIOEscape(e)) return e.error as E | F;\n return e as E | F;\n }\n );\n }\n\n /**\n * Starts this IO as a background computation, returning a `Fiber` handle.\n * The fiber can be joined (await result) or cancelled.\n *\n * `fork()` returns `IO<never, Fiber<E, A>>` — it is lazy and composable.\n * The computation only starts when the outer IO is executed.\n *\n * @returns {IO<never, Fiber<E, A>>} An IO that, when executed, starts this IO and returns a Fiber.\n *\n * @example\n * const io = IO.Do<AppError, string>(async bind => {\n * const fiber = await bind(longRunningTask.fork());\n * // ... do other work ...\n * const result = await fiber.join();\n * return result;\n * });\n */\n fork(): IO<never, Fiber<E, A>> {\n const node = this[NODE];\n return IO.lift(() => {\n const controller = new AbortController();\n const promise = interpret(node, controller.signal);\n return {\n join: () => promise,\n cancel: async () => {\n controller.abort();\n await promise.catch(() => {});\n },\n signal: controller.signal,\n } as Fiber<E, A>;\n });\n }\n\n /**\n * Runs multiple IOs in parallel and combines their results with a function.\n * All IOs are executed concurrently via `Promise.all`. If any IO fails,\n * all errors are collected into a `NonEmptyList`.\n *\n * Supports heterogeneous error types — each IO may have a different error type `E`,\n * and the resulting error is the union of all error types.\n *\n * The last argument is always the combiner function that receives the success values\n * in the same order as the IO arguments.\n *\n * @example\n * const io = IO.parMapN(\n * IO.lift(() => fetchUser()),\n * IO.lift(() => fetchOrders()),\n * (user, orders) => ({ user, orders })\n * );\n */\n static parMapN<E1, E2, A1, A2, R>(\n io1: IO<E1, A1>,\n io2: IO<E2, A2>,\n f: (a1: A1, a2: A2) => R\n ): IO<NonEmptyList<E1 | E2>, R>;\n static parMapN<E1, E2, E3, A1, A2, A3, R>(\n io1: IO<E1, A1>,\n io2: IO<E2, A2>,\n io3: IO<E3, A3>,\n f: (a1: A1, a2: A2, a3: A3) => R\n ): IO<NonEmptyList<E1 | E2 | E3>, R>;\n static parMapN<E1, E2, E3, E4, A1, A2, A3, A4, R>(\n io1: IO<E1, A1>,\n io2: IO<E2, A2>,\n io3: IO<E3, A3>,\n io4: IO<E4, A4>,\n f: (a1: A1, a2: A2, a3: A3, a4: A4) => R\n ): IO<NonEmptyList<E1 | E2 | E3 | E4>, R>;\n static parMapN<E1, E2, E3, E4, E5, A1, A2, A3, A4, A5, R>(\n io1: IO<E1, A1>,\n io2: IO<E2, A2>,\n io3: IO<E3, A3>,\n io4: IO<E4, A4>,\n io5: IO<E5, A5>,\n f: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => R\n ): IO<NonEmptyList<E1 | E2 | E3 | E4 | E5>, R>;\n static parMapN<E1, E2, E3, E4, E5, E6, A1, A2, A3, A4, A5, A6, R>(\n io1: IO<E1, A1>,\n io2: IO<E2, A2>,\n io3: IO<E3, A3>,\n io4: IO<E4, A4>,\n io5: IO<E5, A5>,\n io6: IO<E6, A6>,\n f: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => R\n ): IO<NonEmptyList<E1 | E2 | E3 | E4 | E5 | E6>, R>;\n static parMapN(...ops: any[]): IO<NonEmptyList<any>, any> {\n if (ops.length < 3) {\n return IO.fail(\n NonEmptyList._unsafeFromArray([\n new Error(\"IO.parMapN requires at least two IO arguments and a combiner function\"),\n ])\n );\n }\n const input = ops.slice(0, -1) as IO<any, any>[];\n const combiner = ops[ops.length - 1] as (...args: any[]) => any;\n\n return IO.lift<NonEmptyList<any>, any>(\n async (signal?: AbortSignal) => {\n const results = await Promise.all(input.map((io) => interpret(io[NODE], signal)));\n\n if (results.some((r) => r.type === \"Cancelled\")) {\n ioCancelled();\n }\n\n const errors = results.filter((r): r is Err<any> => r.type === \"Err\").map((r) => r.error);\n\n if (errors.length > 0) {\n throw ioEscape(NonEmptyList._unsafeFromArray(errors));\n }\n\n const values = results.filter((r): r is Ok<any> => r.type === \"Ok\").map((r) => r.value);\n\n return combiner(...values);\n },\n (e: unknown) => {\n if (isIOEscape(e)) return e.error as NonEmptyList<any>;\n return NonEmptyList._unsafeFromArray([e]);\n }\n );\n }\n\n /**\n * Races multiple IOs concurrently, returning the result of the first one to succeed.\n * If all IOs fail, returns a `NonEmptyList` of all errors in the order they were provided.\n *\n * This is useful for implementing fallback strategies where you want the fastest\n * successful response from multiple sources.\n *\n * @template E The error type of the individual IOs.\n * @template A The success type (must be the same for all IOs).\n * @param {...IO<E, A>} ops The IO operations to race.\n * @returns {IO<NonEmptyList<E>, A>} An IO that succeeds with the first result or fails with all errors.\n *\n * @example\n * const io = IO.race(\n * IO.lift(() => fetchFromPrimary()),\n * IO.lift(() => fetchFromFallback()),\n * );\n */\n static race<E, A>(...ops: IO<E, A>[]): IO<NonEmptyList<E>, A> {\n if (ops.length === 0) {\n return IO.fail(\n NonEmptyList._unsafeFromArray([new Error(\"IO.race requires at least one IO argument\") as unknown as E])\n );\n }\n\n return IO.lift<NonEmptyList<E>, A>(\n (signal?: AbortSignal) => {\n return new Promise<A>((resolve, reject) => {\n const controller = new AbortController();\n\n let unlinkParent: (() => void) | undefined;\n if (signal) {\n if (signal.aborted) {\n controller.abort();\n } else {\n const onAbort = () => controller.abort();\n signal.addEventListener(\"abort\", onAbort, { once: true });\n unlinkParent = () => signal.removeEventListener(\"abort\", onAbort);\n }\n }\n\n let completed = 0;\n let settled = false;\n const errors: (E | undefined)[] = new Array(ops.length);\n\n const settle = () => {\n settled = true;\n if (unlinkParent) unlinkParent();\n };\n\n ops.forEach((io, index) => {\n interpret(io[NODE], controller.signal).then((result) => {\n if (settled) return;\n if (result.type === \"Ok\") {\n settle();\n controller.abort();\n resolve(result.value);\n } else if (result.type === \"Err\") {\n errors[index] = result.error;\n completed++;\n if (completed === ops.length) {\n settle();\n const realErrors = errors.filter((e): e is E => e !== undefined);\n if (realErrors.length > 0) {\n reject(ioEscape(NonEmptyList._unsafeFromArray(realErrors)));\n } else {\n reject({ [IO_CANCELLED]: true });\n }\n }\n } else {\n completed++;\n if (completed === ops.length && !settled) {\n settle();\n const realErrors = errors.filter((e): e is E => e !== undefined);\n if (realErrors.length > 0) {\n reject(ioEscape(NonEmptyList._unsafeFromArray(realErrors)));\n } else {\n reject({ [IO_CANCELLED]: true });\n }\n }\n }\n });\n });\n });\n },\n (e: unknown) => {\n if (isIOCancelled(e)) throw e;\n if (isIOEscape(e)) return e.error as NonEmptyList<E>;\n return NonEmptyList._unsafeFromArray([e as E]);\n }\n );\n }\n\n /**\n * Monadic do-notation. Sequences IO operations using an imperative-style\n * `bind` function that unwraps IO values or short-circuits on the first error.\n *\n * Inside the `operation` callback, call `bind(io)` to execute an IO and extract its\n * success value. If any bound IO fails, the entire `Do` short-circuits with that error —\n * subsequent `bind` calls are not executed.\n *\n * Uses an `IOEscape` sentinel internally to preserve the typed error `E` through\n * JavaScript's throw/catch mechanism, ensuring the error channel remains type-safe.\n *\n * When `liftE` is provided, non-IO exceptions thrown inside the operation block\n * (e.g. programming errors, unexpected throws) are transformed into the error type `E`\n * via `liftE`, closing the type hole. Without `liftE`, such exceptions pass through\n * untyped — use with care.\n *\n * @template E The error type shared by all bound IO operations.\n * @template A The final success type produced by the comprehension.\n * @param {(bind: <B>(effect: IO<E, B>) => Promise<B>) => Promise<A>} operation\n * An async function that receives a `bind` callback for unwrapping IO values.\n * @param {(e: unknown) => E} [liftE] Optional function to transform non-IO exceptions into E.\n * @returns {IO<E, A>} An IO that, when executed, runs the comprehension.\n *\n * @example\n * const io = IO.Do<AppError, number>(async bind => {\n * const user = await bind(fetchUser(userId));\n * const orders = await bind(fetchOrders(user.id));\n * return orders.length;\n * });\n */\n static Do<E, A>(\n operation: (bind: <B>(effect: IO<E, B>) => Promise<B>) => Promise<A>,\n liftE?: (e: unknown) => E\n ): IO<E, A> {\n const userLiftE = liftE;\n return IO.lift<E, A>(\n async (signal?: AbortSignal) => {\n const bind = async <B>(eff: IO<E, B>): Promise<B> => {\n const result = await interpret(eff[NODE], signal);\n if (result.type === \"Ok\") {\n return result.value;\n }\n if (result.type === \"Cancelled\") {\n ioCancelled();\n }\n throw ioEscape(result.error);\n };\n return await operation(bind);\n },\n (e: unknown): E => {\n if (isIOCancelled(e)) throw e;\n if (isIOEscape(e)) return e.error as E;\n if (userLiftE) return userLiftE(e);\n return e as E;\n }\n );\n }\n\n /**\n * Sequentially executes a function over each item, collecting results into an array.\n * Fail-fast: if any invocation fails, the remaining items are not processed and the\n * error is returned immediately.\n *\n * @template E The error type.\n * @template A The input item type.\n * @template B The output type for each item.\n * @param {A[]} items The items to traverse.\n * @param {(a: A) => IO<E, B>} f A function that produces an IO for each item.\n * @returns {IO<E, List<B>>} An IO that succeeds with all results as a List, or fails with the first error.\n *\n * @example\n * const io = IO.traverse([1, 2, 3], n => IO.lift(() => n * 2));\n * // result: { type: \"Ok\", value: List [2, 4, 6] }\n */\n static traverse<E, A, B>(items: readonly A[], f: (a: A) => IO<E, B>): IO<E, List<B>> {\n return IO.Do<E, List<B>>(async (bind) => {\n const results: B[] = [];\n for (const item of items) {\n results.push(await bind(f(item)));\n }\n return List._unsafeFromArray(results);\n });\n }\n\n /**\n * Executes a function over each item in parallel, collecting all results or all errors.\n * Unlike `traverse`, all items are processed concurrently. If any fail, all errors\n * are collected into a `NonEmptyList`.\n *\n * @template E The error type.\n * @template A The input item type.\n * @template B The output type for each item.\n * @param {A[]} items The items to traverse in parallel.\n * @param {(a: A) => IO<E, B>} f A function that produces an IO for each item.\n * @returns {IO<NonEmptyList<E>, List<B>>} An IO that succeeds with all results as a List, or fails with all errors.\n *\n * @example\n * const io = IO.parTraverse([1, 2, 3], n => IO.lift(() => n * 2));\n * // result: { type: \"Ok\", value: List [2, 4, 6] }\n */\n static parTraverse<E, A, B>(items: readonly A[], f: (a: A) => IO<E, B>): IO<NonEmptyList<E>, List<B>> {\n return IO.lift<NonEmptyList<E>, List<B>>(\n async (signal?: AbortSignal) => {\n const results = await Promise.all(items.map((item) => interpret(f(item)[NODE], signal)));\n\n if (results.some((r) => r.type === \"Cancelled\")) {\n ioCancelled();\n }\n\n const errors = results.filter((r): r is Err<E> => r.type === \"Err\").map((r) => r.error);\n\n if (errors.length > 0) {\n throw ioEscape(NonEmptyList._unsafeFromArray(errors));\n }\n\n return List._unsafeFromArray(results.filter((r): r is Ok<B> => r.type === \"Ok\").map((r) => r.value));\n },\n (e: unknown) => {\n if (isIOEscape(e)) return e.error as NonEmptyList<E>;\n return NonEmptyList._unsafeFromArray([e as E]);\n }\n );\n }\n\n /**\n * Sequentially executes an array of IOs, collecting results into an array.\n * Equivalent to `traverse(ios, x => x)`. Fail-fast on the first error.\n *\n * @template E The error type.\n * @template A The success type of each IO.\n * @param {IO<E, A>[]} ios The IO operations to sequence.\n * @returns {IO<E, List<A>>} An IO that succeeds with all results as a List, or fails with the first error.\n *\n * @example\n * const io = IO.sequence([IO.lift(() => 1), IO.lift(() => 2), IO.lift(() => 3)]);\n * // result: { type: \"Ok\", value: List [1, 2, 3] }\n */\n static sequence<E, A>(ios: readonly IO<E, A>[]): IO<E, List<A>> {\n return IO.traverse(ios, (io) => io);\n }\n\n /**\n * Executes an array of IOs in parallel, collecting all results or all errors.\n * Equivalent to `parTraverse(ios, x => x)`.\n *\n * @template E The error type.\n * @template A The success type of each IO.\n * @param {IO<E, A>[]} ios The IO operations to execute in parallel.\n * @returns {IO<NonEmptyList<E>, List<A>>} An IO that succeeds with all results as a List, or fails with all errors.\n *\n * @example\n * const io = IO.parSequence([IO.lift(() => 1), IO.lift(() => 2), IO.lift(() => 3)]);\n * // result: { type: \"Ok\", value: List [1, 2, 3] }\n */\n static parSequence<E, A>(ios: readonly IO<E, A>[]): IO<NonEmptyList<E>, List<A>> {\n return IO.parTraverse(ios, (io) => io);\n }\n}\n","/**\n * `Eval` represents a deferred computation, which allows operations to be delayed, chained,\n * and lazily evaluated. It provides a foundation for creating different types of deferred operations\n * that can be evaluated on demand.\n *\n * Its primary goal is to facilitate the construction and manipulation of computations in a way\n * that allows for efficient and flexible execution strategies. It can create immediate, deferred,\n * and lazy computations, and compose them using monadic operations.\n *\n * @template A The type of the value that this computation produces.\n */\nexport abstract class Eval<A> {\n /**\n * Retrieves the value of the operation.\n * This is an internal method used by the trampoline interpreter. External code should\n * always use `evaluate()` instead — calling `value()` directly on `Map` or `FlatMap`\n * nodes throws an `EvaluationError`.\n *\n * @internal\n * @returns {A} The value produced by the operation.\n */\n protected abstract value(): A;\n\n /**\n * Creates a deferred operation that will be evaluated later.\n * The provided function is not executed until the value of the operation is needed.\n *\n * This method is useful for deferring expensive computations until their results are required,\n * thereby improving performance and resource utilization.\n *\n * @template A The type of the value that the operation produces.\n * @param {() => A} f The function to defer, which produces the operation's value when called.\n * @returns {Eval<A>} A new deferred operation.\n *\n * @example\n * // Defers the computation of a value\n * const deferredEval = Eval.defer(() => {\n * console.log(\"Computing value...\");\n * return 42;\n * });\n *\n * // The value is not computed until we call `evaluate`\n * console.log(deferredEval.evaluate()); // Logs \"Computing value...\" then 42\n */\n static defer<A>(f: () => A): Eval<A> {\n return new Deferred(f);\n }\n\n /**\n * Creates an immediate operation with a given value.\n * The provided value is available immediately without any deferred computation.\n *\n * This method is useful for wrapping a value in an `Eval` instance when the value is already\n * computed, and the evaluation does not need to be deferred.\n *\n * @template A The type of the value that the operation produces.\n * @param {A} value The value to wrap in an immediate operation.\n * @returns {Eval<A>} A new immediate operation.\n *\n * @example\n * // Wraps an immediate value in an Eval instance\n * const immediateEval = Eval.pure(42);\n *\n * // The value is available immediately\n * console.log(immediateEval.evaluate()); // Logs 42\n */\n static pure<A>(value: A): Eval<A> {\n return new Now(value);\n }\n\n /**\n * Creates a lazy operation that will be evaluated once when needed.\n * The provided function is evaluated the first time the value is requested, and the result is cached\n * for subsequent accesses.\n *\n * This method is useful for deferring the computation until it is needed, while ensuring that the computation\n * is performed at most once, thereby combining the benefits of deferred and memoized evaluation.\n *\n * @template A The type of the value that the operation produces.\n * @param {() => A} f The function to lazily evaluate, which produces the operation's value when called.\n * @returns {Eval<A>} A new lazy operation.\n *\n * @example\n * // Lazily computes a value\n * const lazyEval = Eval.lazy(() => {\n * console.log(\"Computing value...\");\n * return 42;\n * });\n *\n * // The value is not computed until `evaluate` is called the first time\n * console.log(lazyEval.evaluate()); // Logs \"Computing value...\" then 42\n *\n * // Subsequent calls do not recompute the value\n * console.log(lazyEval.evaluate()); // Logs 42\n */\n static lazy<A>(f: () => A): Eval<A> {\n return new Lazy(f);\n }\n\n /**\n * Transforms the result of the operation using a given function.\n * The provided function is applied to the value produced by this operation, and the result is wrapped\n * in a new `Eval` instance.\n *\n * It allows for chaining operations in a functional style, enabling the transformation of values\n * as part of a sequence of computations.\n *\n * @template A The type of the result before transformation.\n * @template B The type of the result after transformation.\n * @param {(a: A) => B} f The transformation function that takes a value of type `A` and returns a value of type `B`.\n * @returns {Eval<B>} A new operation representing the transformed result.\n *\n * @example\n * // Creates an immediate operation with an initial value\n * const immediateEval = Eval.now(42);\n *\n * // Transforms the value by adding 1\n * const mappedEval = immediateEval.map(value => value + 1);\n *\n * // Evaluates the transformed operation\n * console.log(mappedEval.evaluate()); // Logs 43\n */\n map<B>(f: (a: A) => B): Eval<B> {\n return new Map(this, f);\n }\n\n /**\n * Composes this operation with another operation.\n * The provided function takes the result of this operation and returns a new `Eval` instance,\n * allowing for the creation of a sequence of dependent computations.\n *\n * This method is useful for chaining multiple computations that may have dependencies on each other,\n * enabling a monadic style of composition where each step can produce a new deferred computation.\n *\n * @template A The type of the result before composition.\n * @template B The type of the result of the composed operation.\n * @param {(a: A) => Eval<B>} f The function to compose with, which takes a value of type `A`\n * and returns a new `Eval` instance producing a value of type `B`.\n * @returns {Eval<B>} A new operation representing the composed result.\n *\n * @example\n * // Creates an immediate operation with an initial value\n * const immediateEval = Eval.now(42);\n *\n * // Composes the initial operation with another operation that adds 1 and wraps it in Eval\n * const flatMappedEval = immediateEval.flatMap(value => Eval.now(value + 1));\n *\n * // Evaluates the composed operation\n * console.log(flatMappedEval.evaluate()); // Logs 43\n */\n flatMap<B>(f: (a: A) => Eval<B>): Eval<B> {\n return new FlatMap(this, f);\n }\n\n /**\n * Evaluates the operation, including any composed operations.\n * It uses an iterative approach with a stack to handle nested operations, ensuring\n * that the computation is performed in the correct order and avoiding stack overflow from deep recursion.\n *\n * It is essential for obtaining the final result of an `Eval` computation, especially when\n * multiple operations are chained together.\n *\n * @template A The type of the final result of the computation.\n * @returns {A} The final result of the computation.\n * @throws {EvaluationError} If there is an unexpected issue during evaluation, such as an undefined function in the stack.\n *\n * @example\n * // Creates a deferred operation\n * const deferredEval = Eval.defer(() => 21);\n *\n * // Composes the deferred operation with another operation\n * const composedEval = deferredEval.flatMap(value => Eval.now(value * 2));\n *\n * // Evaluates the composed operation\n * console.log(composedEval.evaluate()); // Logs 42\n */\n /* eslint-disable @typescript-eslint/no-this-alias */\n evaluate(): A {\n let current: Eval<A> = this;\n const stack: Array<(a: any) => Eval<A>> = [];\n\n while (true) {\n if (current instanceof FlatMap) {\n const inner = current.first;\n if (inner instanceof FlatMap || inner instanceof Map) {\n stack.push(current.f);\n current = inner;\n } else {\n current = current.f(inner.value());\n }\n } else if (current instanceof Map) {\n const maps: Array<(a: any) => any> = [current.f];\n let inner: Eval<any> = current.first;\n while (inner instanceof Map) {\n maps.push(inner.f);\n inner = inner.first;\n }\n const applyMaps = (val: any) => {\n for (let i = maps.length - 1; i >= 0; i--) {\n val = maps[i](val);\n }\n return val;\n };\n if (inner instanceof FlatMap) {\n stack.push((a) => new Now(applyMaps(a)));\n current = inner;\n } else {\n const result = applyMaps(inner.value());\n if (stack.length === 0) {\n return result;\n }\n current = stack.pop()!(result);\n }\n } else {\n const result = current.value();\n if (stack.length === 0) {\n return result;\n }\n current = stack.pop()!(result);\n }\n }\n }\n}\n\n/**\n * Represents an immediate computation. The value is precomputed and available immediately without any delay.\n *\n * The `Now` class is useful when you have a value that is already computed, and you want to wrap it\n * in an `Eval` instance to integrate with other deferred computations.\n *\n * @template A The type of the value that this computation produces.\n */\nclass Now<A> extends Eval<A> {\n /**\n * Creates an instance of `Now` with a given value.\n */\n constructor(private readonly _value: A) {\n super();\n }\n\n /**\n * Retrieves the immediate value of the computation.\n *\n * @returns {A} The precomputed value.\n *\n * @example\n * // Creates an immediate computation with the value 42\n * const immediateEval = new Now(42);\n *\n * // Retrieves the value immediately\n * console.log(immediateEval.value()); // Logs 42\n */\n value(): A {\n return this._value;\n }\n}\n\n/**\n * Represents a deferred computation. The computation is not performed until the value is explicitly requested.\n * The `Deferred` class is useful for deferring expensive or time-consuming computations until their results are needed.\n *\n * @template A The type of the value that this computation produces.\n */\nclass Deferred<A> extends Eval<A> {\n /**\n * Creates an instance of `Deferred` with a given f function.\n *\n * @param {() => A} f The function to defer, which produces the computation's value when called.\n */\n constructor(private readonly f: () => A) {\n super();\n }\n\n /**\n * Performs the deferred computation and returns the result.\n *\n * @returns {A} The value produced by the deferred computation.\n *\n * @example\n * // Creates a deferred computation\n * const deferredEval = new Deferred(() => {\n * console.log(\"Computing value...\");\n * return 42;\n * });\n *\n * // The computation is not performed until `value` is called\n * console.log(deferredEval.value()); // Logs \"Computing value...\" then 42\n */\n value(): A {\n return this.f();\n }\n}\n\n/**\n * Represents a lazy computation that will be evaluated once.\n * The provided function is evaluated the first time the value is requested, and the result is cached\n * for subsequent accesses.\n *\n * The `Lazy` class is useful for deferring the computation until it is needed, while ensuring that the computation\n * is performed at most once. This combines the benefits of deferred and memoized evaluation.\n *\n * @template A The type of the value that this computation produces.\n */\nclass Lazy<A> extends Eval<A> {\n private _value?: A;\n private _evaluated = false;\n\n /**\n * Creates an instance of `Lazy` with a given f function.\n *\n * @param {() => A} f The function to lazily evaluate, which produces the operation's value when called.\n */\n constructor(private readonly f: () => A) {\n super();\n }\n\n /**\n * Performs the lazy computation if it has not been done yet, caches the result, and returns the value.\n *\n * @returns {A} The value produced by the lazy computation.\n *\n * @example\n * // Creates a lazy computation\n * const lazyEval = new Lazy(() => {\n * console.log(\"Computing value...\");\n * return 42;\n * });\n *\n * // The computation is not performed until `value` is called the first time\n * console.log(lazyEval.value()); // Logs \"Computing value...\" then 42\n *\n * // Subsequent calls do not recompute the value\n * console.log(lazyEval.value()); // Logs 42\n */\n value(): A {\n if (!this._evaluated) {\n this._value = this.f();\n this._evaluated = true;\n }\n return this._value!;\n }\n}\n\n/**\n * Represents a computation that is the result of a flatMap operation.\n * A `FlatMap` allows for the composition of multiple computations where each computation\n * can depend on the result of the previous one.\n *\n * The `FlatMap` class is used internally to chain computations in a monadic style. It extends the `Eval`\n * abstract class and implements the `value` method to throw an error, as a `FlatMap` should not be\n * directly evaluated. Instead, its evaluation is handled by the `Eval` class's `evaluate` method.\n *\n * @template A The type of the value produced by the first computation.\n * @template B The type of the value produced by the composed computation.\n */\nclass FlatMap<A, B> extends Eval<B> {\n /**\n * Creates an instance of `FlatMap` with a given initial computation and a function to compose with.\n *\n * @param {Eval<A>} first The initial computation.\n * @param {(a: A) => Eval<B>} f The function to compose with, which takes a value of type `A`\n * and returns a new `Eval` instance producing a value of type `B`.\n */\n constructor(\n public readonly first: Eval<A>,\n public readonly f: (a: A) => Eval<B>\n ) {\n super();\n }\n\n /**\n * This method should not be called directly. It is implemented to throw an error because\n * a `FlatMap` should not be evaluated directly. Instead, its evaluation is managed by the `Eval` class's\n * `evaluate` method.\n *\n * @throws {EvaluationError} Always throws an error indicating that `FlatMap` should not be evaluated directly.\n */\n value(): B {\n throw new EvaluationError(\"FlatMap should not be evaluated directly\");\n }\n}\n\n/**\n * Represents a transformation of a computation's result. Unlike `FlatMap`, the mapping function\n * returns a plain value rather than an `Eval` instance. Consecutive `Map` nodes are fused into\n * a single composed function during evaluation, avoiding intermediate allocations and stack growth.\n *\n * @template A The type of the value produced by the source computation.\n * @template B The type of the value after transformation.\n */\nclass Map<A, B> extends Eval<B> {\n constructor(\n public readonly first: Eval<A>,\n public readonly f: (a: A) => B\n ) {\n super();\n }\n\n value(): B {\n throw new EvaluationError(\"Map should not be evaluated directly\");\n }\n}\n\n/**\n * Represents an error that occurs during the evaluation of a computation.\n *\n * The `EvaluationError` class extends the standard `Error` class to provide additional context\n * specific to errors encountered during the evaluation of `Eval` computations. This class includes\n * the original error that caused the evaluation to fail, allowing for more detailed error handling\n * and debugging.\n *\n * @template E The type of the error details.\n */\nexport class EvaluationError<E> extends Error {\n /**\n * Creates an instance of `EvaluationError` with the specified error details.\n *\n * @param {E} error The details of the error that occurred during evaluation.\n */\n constructor(readonly error: E) {\n super();\n this.name = \"EvaluationError\";\n }\n}\n","/**\n * The `Reader` type is a construct that allows for\n * dependency injection without side effects, promoting cleaner and more\n * maintainable code. It encapsulates an environment and provides it implicitly\n * to functions that require it, avoiding the need to pass dependencies\n * explicitly through every layer of an application.\n *\n * The `Reader` type supports various operations, including mapping,\n * flatMapping, lifting functions into the Reader context, and combining\n * multiple Reader instances. It is particularly useful in scenarios where\n * managing dependencies such as configurations or shared resources can become\n * cumbersome and error-prone.\n *\n * Type Parameters:\n * - `R`: The type of the environment that the Reader depends on.\n * - `A`: The type of the value produced by the Reader computation.\n *\n * `Reader` is **synchronous**: `run(env)` returns the carried value `A` directly, with no\n * implicit `Promise` wrapping. If `A` itself is a `Promise` (because the computation produced\n * one), you `await` that value as usual — but the `await` is on the value, not on `run`.\n *\n * Usage Example:\n * ```typescript\n * // Define an environment type\n * type Env = { multiplier: number };\n *\n * // A Reader that reads the environment and computes a value synchronously\n * const doubled = Reader.ask<Env>().map(env => env.multiplier * 2);\n *\n * const value = doubled.run({ multiplier: 21 }); // 42 — returned synchronously\n *\n * // If the carried value is a Promise, await the value (run is still synchronous):\n * const fetchData = Reader.ask<Env & { apiEndpoint: string }>().map(env =>\n * fetch(`${env.apiEndpoint}/data`).then(response => response.json())\n * );\n * const data = await fetchData.run({ multiplier: 1, apiEndpoint: 'https://api.example.com' });\n * ```\n */\nexport class Reader<R, A> {\n /**\n * Initializes a new `Reader` instance.\n *\n * A `Reader` represents a computation that needs an environment `R` to produce\n * a value of type `A`. This makes it easier to manage dependencies and side effects\n * in a functional programming style, promoting cleaner and more maintainable code.\n *\n * @param {function(R): A} f - A function that takes an environment of type `R`\n * and returns a value of type `A`.\n *\n * @example\n * // Define an environment type\n * type Env = { apiEndpoint: string };\n *\n * // Define a function that uses the environment to fetch data\n * const fetchData = (env: Env) => fetch(`${env.apiEndpoint}/data`).then(response => response.json());\n *\n * // Create a Reader instance with the function\n * const reader = new Reader(fetchData);\n *\n * // Define an environment\n * const env: Env = { apiEndpoint: 'https://api.example.com' };\n *\n * // Run the Reader with the provided environment\n * reader.run(env).then(data => console.log(data));\n */\n public constructor(private f: (env: R) => A) {}\n\n /**\n * Creates a new `Reader` instance that ignores the environment and always returns\n * the provided value.\n *\n * This is useful for lifting a value into the `Reader` context, allowing\n * you to work with the value in a way that is consistent with other `Reader` computations\n * without requiring any environment.\n *\n * @param value - The value to be returned by the `Reader`.\n * @returns A new `Reader` instance that always returns the provided value.\n *\n * @example\n * // Creating a Reader that always returns the value 42\n * const reader = Reader.pure<number, number>(42);\n *\n * // Running the Reader with any environment will always return 42\n * console.log(reader.run(10)); // 42\n * console.log(reader.run({})); // 42\n */\n static pure<R, A>(value: A): Reader<R, A> {\n return new Reader(() => value);\n }\n\n /**\n * Transforms the result of the `Reader` computation by applying the provided\n * function to its value.\n *\n * This allows you to change the value produced by the `Reader` without\n * altering the environment. It is useful for chaining operations in a functional\n * style, where each step can modify the result of the previous computation.\n *\n * @param f - A function that takes the result of the `Reader` and returns a new value.\n * @returns A new `Reader` instance that applies the transformation function to the result.\n *\n * @example\n * // Creating a Reader that returns the length of a string from the environment\n * const reader = Reader.ask<string>().map(env => env.length);\n *\n * // Running the Reader with an environment string will return its length\n * console.log(reader.run(\"Hello, world!\")); // 13\n * console.log(reader.run(\"TypeScript\")); // 10\n */\n map<B>(f: (a: A) => B): Reader<R, B> {\n return new Reader((env: R) => f(this.run(env)));\n }\n\n /**\n * Chains a new `Reader` computation to the result of the current `Reader`.\n *\n * This method allows you to sequence `Reader` operations, where the result of one\n * computation can determine the next computation. It is useful for creating complex\n * workflows that depend on the environment and previous results.\n *\n * @param f - A function that takes the result of the current `Reader` and returns a new `Reader`.\n * @returns A new `Reader` instance that represents the chained computation.\n *\n * @example\n * // Creating a Reader that fetches data and then processes it\n * const fetchData = Reader.ask<{ apiEndpoint: string }>().flatMap(env =>\n * Reader.pure(fetch(`${env.apiEndpoint}/data`).then(response => response.json()))\n * );\n *\n * const processData = fetchData.flatMap(data =>\n * Reader.pure(data.map(item => item.value))\n * );\n *\n * // Running the Reader with an environment will fetch and process the data\n * processData.run({ apiEndpoint: 'https://api.example.com' }).then(console.log);\n */\n flatMap<B>(f: (a: A) => Reader<R, B>): Reader<R, B> {\n return new Reader((env: R) => f(this.run(env)).run(env));\n }\n\n /**\n * Creates a `Reader` instance that provides access to the environment.\n *\n * This is useful when you need to obtain the environment itself\n * within a `Reader` computation. It returns a `Reader` that, when run, simply\n * returns the environment.\n *\n * @returns A new `Reader` instance that returns the environment.\n *\n * @example\n * // Creating a Reader that returns the environment\n * const reader = Reader.ask<{ apiEndpoint: string }>();\n *\n * // Running the Reader will return the provided environment\n * const env = { apiEndpoint: 'https://api.example.com' };\n * console.log(reader.run(env)); // { apiEndpoint: 'https://api.example.com' }\n *\n * // Combining with map to access a specific part of the environment\n * const apiEndpointReader = reader.map(env => env.apiEndpoint);\n * console.log(apiEndpointReader.run(env)); // 'https://api.example.com'\n */\n static ask<R>(): Reader<R, R> {\n return new Reader((env: R) => env);\n }\n\n /**\n * Lifts a function into the `Reader` context, allowing it to be applied\n * to the result of a `Reader` computation.\n *\n * This static method is useful for transforming the result of a `Reader`\n * using a regular function. It takes a function that operates on a value\n * and returns a new function that operates on a `Reader`.\n *\n * @param f - A function that takes a value and returns a new value.\n * @returns A function that takes a `Reader` and returns a new `Reader` with the transformed result.\n *\n * @example\n * // Define a function to be lifted\n * const toUpperCase = (s: string) => s.toUpperCase();\n *\n * // Create a Reader that reads a string from the environment\n * const reader = Reader.ask<string>();\n *\n * // Lift the function into the Reader context\n * const upperCaseReader = Reader.lift(toUpperCase)(reader);\n *\n * // Running the Reader will apply the function to the environment value\n * console.log(upperCaseReader.run(\"hello\")); // \"HELLO\"\n * console.log(upperCaseReader.run(\"world\")); // \"WORLD\"\n */\n static lift<R, A, B>(f: (a: A) => B): (ra: Reader<R, A>) => Reader<R, B> {\n return (ra: Reader<R, A>) => ra.map(f);\n }\n\n /**\n * Combines multiple `Reader` instances into a single `Reader` that produces a tuple\n * of their results when run with the same environment.\n *\n * This is useful for executing multiple `Reader` computations\n * in parallel and collecting their results into a single value.\n *\n * @param readers - An array of `Reader` instances to be combined.\n * @returns A new `Reader` instance that returns a tuple of the results of the given `Reader` instances.\n *\n * @example\n * // Create multiple Readers that read different values from the environment\n * const readerA = Reader.ask<{ valueA: number, valueB: string, valueC: boolean }>().map(env => env.valueA);\n * const readerB = Reader.ask<{ valueA: number, valueB: string, valueC: boolean }>().map(env => env.valueB);\n * const readerC = Reader.ask<{ valueA: number, valueB: string, valueC: boolean }>().map(env => env.valueC);\n *\n * // Combine the Readers\n * const combinedReader = Reader.parZip(readerA, readerB, readerC);\n *\n * // Running the combined Reader will return a tuple of the results\n * const env = { valueA: 42, valueB: \"hello\", valueC: true };\n * console.log(combinedReader.run(env)); // [42, \"hello\", true]\n */\n static parZip<R, const A extends readonly unknown[]>(...readers: { [K in keyof A]: Reader<R, A[K]> }): Reader<R, A> {\n return new Reader((env: R) => readers.map((reader) => reader.run(env)) as unknown as A);\n }\n\n /**\n * Creates a new `Reader` that applies a transformation to the environment before\n * running the provided `Reader` computation.\n *\n * This static method is useful for temporarily modifying the environment for a specific\n * computation, allowing you to adjust the context in which the `Reader` runs without\n * affecting the broader environment.\n *\n * @param f - A function that takes the current environment and returns a modified environment.\n * @param reader - The `Reader` instance to run with the modified environment.\n * @returns A new `Reader` instance that runs the provided `Reader` with the transformed environment.\n *\n * @example\n * // Define an environment type\n * type Env = { apiEndpoint: string, version: string };\n *\n * // Create a Reader that reads the API endpoint from the environment\n * const reader = Reader.ask<Env>().map(env => env.apiEndpoint);\n *\n * // Define a function to modify the environment\n * const upgradeApi = (env: Env) => ({ ...env, version: 'v2' });\n *\n * // Create a new Reader that uses the modified environment\n * const modifiedReader = Reader.local(upgradeApi, reader);\n *\n * // Define an example environment\n * const env: Env = { apiEndpoint: 'https://api.example.com', version: 'v1' };\n *\n * // Run the original Reader with the example environment\n * console.log(reader.run(env)); // 'https://api.example.com'\n *\n * // Run the modified Reader with the example environment\n * console.log(modifiedReader.run(env)); // 'https://api.example.com'\n */\n static local<R, A>(f: (env: R) => R, reader: Reader<R, A>): Reader<R, A> {\n return new Reader((env: R) => reader.run(f(env)));\n }\n\n /**\n * Executes the `Reader` computation with the given environment.\n *\n * This method is used to run the `Reader` and obtain its result by providing\n * the necessary environment. It applies the environment to the encapsulated\n * function and returns the computed value.\n *\n * @param env - The environment to be provided to the `Reader` computation.\n * @returns The result of the `Reader` computation.\n *\n * @example\n * // Define an environment type\n * type Env = { apiEndpoint: string };\n *\n * // Create a Reader that reads the API endpoint from the environment\n * const reader = Reader.ask<Env>().map(env => env.apiEndpoint);\n *\n * // Define an example environment\n * const env: Env = { apiEndpoint: 'https://api.example.com' };\n *\n * // Run the Reader with the example environment\n * console.log(reader.run(env)); // 'https://api.example.com'\n */\n run(env: R): A {\n return this.f(env);\n }\n}\n","/**\n * Represents the result of comparing two values, encapsulating the possible outcomes of an ordering comparison.\n * The `Ordering` class provides a type-safe and expressive way to handle comparison results,\n * offering methods and static properties to facilitate common operations in sorting and comparison logic.\n *\n * **Possible Values of `Ordering`**:\n *\n * - `Ordering.LessThan` (alias `LT`): Indicates that the first value is less than the second.\n * - `Ordering.Equal` (alias `EQ`): Indicates that the first value is equal to the second.\n * - `Ordering.GreaterThan` (alias `GT`): Indicates that the first value is greater than the second.\n *\n * **Key Features**:\n *\n * - **Type Safety**: Encapsulates comparison results, reducing errors associated with using raw numeric values.\n * - **Functional Methods**: Provides methods like `match`, `flatMap`, `concat`, and `reverse` to work with ordering values in a functional style.\n * - **Comparator Utilities**: Includes static methods `from`, `comparing`, and `compareBy` to create and combine comparator functions.\n *\n * **Usage Examples**:\n *\n * **Basic Comparison**:\n *\n * ```typescript\n * const a = 5;\n * const b = 10;\n * const ordering = Ordering.from(a - b);\n *\n * ordering.match(\n * () => console.log('a is less than b'),\n * () => console.log('a is equal to b'),\n * () => console.log('a is greater than b')\n * );\n * // Output: 'a is less than b'\n * ```\n *\n * **Sorting an Array**:\n *\n * ```typescript\n * const numbers = [3, 1, 4, 1, 5];\n * numbers.sort((a, b) => Ordering.from(a - b).value);\n * console.log(numbers);\n * // Output: [1, 1, 3, 4, 5]\n * ```\n *\n * **Using Comparators with Complex Types**:\n *\n * ```typescript\n * interface User {\n * age: number;\n * name: string;\n * }\n *\n * const users: User[] = [\n * { age: 30, name: 'Charlie' },\n * { age: 25, name: 'Alice' },\n * { age: 30, name: 'Bob' },\n * ];\n *\n * const compareByAge = Ordering.comparing<User, number>(\n * (u) => u.age,\n * (a, b) => a - b\n * );\n *\n * const compareByName = Ordering.comparing<User, string>(\n * (u) => u.name,\n * (a, b) => a.localeCompare(b)\n * );\n *\n * const userComparator = Ordering.compareBy(compareByAge, compareByName);\n *\n * users.sort((a, b) => userComparator(a, b).value);\n * console.log(users);\n * // Output:\n * // [\n * // { age: 25, name: 'Alice' },\n * // { age: 30, name: 'Bob' },\n * // { age: 30, name: 'Charlie' }\n * // ]\n * ```\n *\n * **Chaining Comparisons**:\n *\n * ```typescript\n * interface User {\n * name: string;\n * age: number;\n * }\n *\n * const user1: User = { name: 'Alice', age: 30 };\n * const user2: User = { name: 'Alice', age: 25 };\n *\n * const ordering = Ordering.from(user1.name.localeCompare(user2.name)).flatMap(() =>\n * Ordering.from(user1.age - user2.age)\n * );\n *\n * ordering.match(\n * () => console.log('user1 comes before user2'),\n * () => console.log('user1 and user2 are equal'),\n * () => console.log('user1 comes after user2')\n * );\n * // Output: 'user1 comes after user2' (because 30 > 25)\n * ```\n *\n * **Reversing an Ordering**:\n *\n * ```typescript\n * const a = 5;\n * const b = 10;\n * const ordering = Ordering.from(a - b).reverse();\n * console.log(ordering.type); // Output: 'GreaterThan'\n * ```\n *\n * **Design Considerations**:\n *\n * - **Immutability**: The `Ordering` instances are immutable and can be safely reused.\n * - **Singleton Instances**: Uses static instances for `LessThan`, `Equal`, and `GreaterThan` to prevent unnecessary object creation.\n *\n * **Aliases**:\n *\n * - `LT`: Alias for `Ordering.LessThan`\n * - `EQ`: Alias for `Ordering.Equal`\n * - `GT`: Alias for `Ordering.GreaterThan`\n *\n * **Common Use Cases**:\n *\n * - Implementing custom sorting logic for arrays and collections.\n * - Comparing optional values or complex data structures.\n * - Building composite comparators for multi-level sorting criteria.\n *\n * @export\n * @class Ordering\n */\nexport class Ordering {\n private constructor(\n public readonly value: -1 | 0 | 1,\n public readonly type: \"LessThan\" | \"Equal\" | \"GreaterThan\"\n ) {}\n\n /**\n * Indicates that the first value is less than the second.\n * @static\n * @type {Ordering}\n */\n static readonly LessThan: Ordering = new Ordering(-1, \"LessThan\");\n\n /**\n * Indicates that the first value is equal to the second.\n * @static\n * @type {Ordering}\n */\n static readonly Equal: Ordering = new Ordering(0, \"Equal\");\n\n /**\n * Indicates that the first value is greater than the second.\n * @static\n * @type {Ordering}\n */\n static readonly GreaterThan: Ordering = new Ordering(1, \"GreaterThan\");\n\n /**\n * Chains multiple `Ordering` computations, allowing for sequential comparisons based on multiple criteria.\n *\n * - If the current `Ordering` is `Equal`, it invokes the provided function `f` to obtain the next `Ordering`.\n * - If the current `Ordering` is `LessThan` or `GreaterThan`, it returns the current `Ordering` without invoking `f`.\n *\n * This method is useful when you have multiple comparison criteria and want to proceed to the next\n * comparison only if previous ones are equal. It enables the construction of composite comparisons in a functional and readable manner.\n *\n * @param {() => Ordering} f - A function that returns the next `Ordering` to consider if the current `Ordering` is `Equal`.\n * @returns {Ordering} The current `Ordering` if it is `LessThan` or `GreaterThan`; otherwise, the result of invoking `f`.\n *\n * @example\n * // Example: Comparing users by name, then by age if names are equal\n * interface User {\n * name: string;\n * age: number;\n * }\n *\n * const user1: User = { name: 'Alice', age: 30 };\n * const user2: User = { name: 'Alice', age: 25 };\n *\n * const ordering = Ordering.from(user1.name.localeCompare(user2.name)).flatMap(() =>\n * Ordering.from(user1.age - user2.age)\n * );\n *\n * ordering.match(\n * () => console.log('user1 comes before user2'),\n * () => console.log('user1 and user2 are equal'),\n * () => console.log('user1 comes after user2')\n * );\n * // Output: 'user1 comes after user2' (because 30 > 25)\n */\n flatMap(f: () => Ordering): Ordering {\n return this.type === \"Equal\" ? f() : this;\n }\n\n /**\n * Executes one of the provided functions based on the current `Ordering`, effectively performing pattern matching.\n *\n * - If the `Ordering` is `LessThan`, it invokes `onLessThan`.\n * - If the `Ordering` is `Equal`, it invokes `onEqual`.\n * - If the `Ordering` is `GreaterThan`, it invokes `onGreaterThan`.\n *\n * This method allows you to handle each possible outcome of an `Ordering` explicitly, similar to pattern matching in functional programming languages.\n *\n * @template B The return type of the provided functions and the `match` method.\n * @param {() => B} onLessThan - Function to execute if the `Ordering` is `LessThan`.\n * @param {() => B} onEqual - Function to execute if the `Ordering` is `Equal`.\n * @param {() => B} onGreaterThan - Function to execute if the `Ordering` is `GreaterThan`.\n * @returns {B} The result of the function corresponding to the current `Ordering`.\n *\n * @example\n * const a = 5;\n * const b = 10;\n * const ordering = Ordering.from(a - b);\n * const message = ordering.match(\n * () => 'a is less than b',\n * () => 'a is equal to b',\n * () => 'a is greater than b'\n * );\n * console.log(message);\n * // Output: 'a is less than b'\n */\n match<B>(onLessThan: () => B, onEqual: () => B, onGreaterThan: () => B): B {\n switch (this.type) {\n case \"LessThan\":\n return onLessThan();\n case \"Equal\":\n return onEqual();\n case \"GreaterThan\":\n return onGreaterThan();\n }\n }\n\n /**\n * Reverses the current `Ordering`, effectively inverting the comparison result.\n *\n * - `LessThan` becomes `GreaterThan`\n * - `GreaterThan` becomes `LessThan`\n * - `Equal` remains `Equal`\n *\n * This method is useful when you want to invert the sorting order or reverse the result of a comparison.\n *\n * @returns {Ordering} The reversed `Ordering`.\n *\n * @example\n * // Example: Reversing the ordering to sort numbers in descending order\n * const numbers = [1, 2, 3, 4, 5];\n *\n * // Sort in ascending order\n * numbers.sort((a, b) => Ordering.from(a - b).value);\n * console.log(numbers);\n * // Output: [1, 2, 3, 4, 5]\n *\n * // Sort in descending order using reverse()\n * numbers.sort((a, b) => Ordering.from(a - b).reverse().value);\n * console.log(numbers);\n * // Output: [5, 4, 3, 2, 1]\n */\n reverse(): Ordering {\n switch (this.type) {\n case \"LessThan\":\n return Ordering.GreaterThan;\n case \"Equal\":\n return Ordering.Equal;\n case \"GreaterThan\":\n return Ordering.LessThan;\n }\n }\n\n /**\n * Performs a side effect based on the current `Ordering` and returns the `Ordering` unchanged.\n *\n * This method is useful for executing side effects (such as logging, debugging, or updating external state) without interrupting the flow of method chaining. It allows you to observe or react to the current `Ordering` while continuing to work with it in a fluent interface style.\n *\n * @param {(ordering: Ordering) => void} f - A function that takes the current `Ordering` as an argument and performs a side effect.\n * @returns {Ordering} The current `Ordering`, allowing for method chaining.\n *\n * @example\n * // Example: Logging the Ordering during a comparison\n * const a = 5;\n * const b = 10;\n *\n * const ordering = Ordering.from(a - b).tap(o => console.log(`Ordering is: ${o.type}`));\n * // Output: 'Ordering is: LessThan'\n *\n * // Continue using the ordering\n * ordering.match(\n * () => console.log('a is less than b'),\n * () => console.log('a is equal to b'),\n * () => console.log('a is greater than b')\n * );\n * // Output: 'a is less than b'\n */\n tap(f: (ordering: Ordering) => void): Ordering {\n f(this);\n return this;\n }\n\n /**\n * Combines this `Ordering` with another `Ordering`, returning the first non-`Equal` result.\n *\n * - If the current `Ordering` is not `Equal` (`LessThan` or `GreaterThan`), it returns the current `Ordering`.\n * - If the current `Ordering` is `Equal`, it returns the `other` `Ordering`.\n *\n * This method is useful when you have multiple comparison criteria and want to determine the overall `Ordering` by considering each criterion in sequence. It allows you to combine two `Ordering` instances, effectively cascading the comparison to the next criterion if the current one is inconclusive (`Equal`).\n *\n * @param {Ordering} other - The next `Ordering` to consider if the current `Ordering` is `Equal`.\n * @returns {Ordering} The first non-`Equal` `Ordering`; if both are `Equal`, returns `Equal`.\n *\n * @example\n * // Example: Combining orderings to compare strings by length and then alphabetically\n * const compareByLength = (a: string, b: string): Ordering =>\n * Ordering.from(a.length - b.length);\n *\n * const compareAlphabetically = (a: string, b: string): Ordering =>\n * Ordering.from(a.localeCompare(b));\n *\n * const compareStrings = (a: string, b: string): Ordering =>\n * compareByLength(a, b).concat(compareAlphabetically(a, b));\n *\n * const result = compareStrings('apple', 'banana');\n *\n * result.match(\n * () => console.log('\"apple\" comes before \"banana\"'),\n * () => console.log('\"apple\" and \"banana\" are equal'),\n * () => console.log('\"apple\" comes after \"banana\"')\n * );\n * // Output: '\"apple\" comes before \"banana\"' (because 'apple' is shorter than 'banana')\n *\n * @example\n * // Using concat in sorting an array of strings by length, then alphabetically\n * const fruits = ['kiwi', 'apple', 'banana', 'cherry', 'date'];\n *\n * const compareByLength = (a: string, b: string): Ordering =>\n * Ordering.from(a.length - b.length);\n *\n * const compareAlphabetically = (a: string, b: string): Ordering =>\n * Ordering.from(a.localeCompare(b));\n *\n * fruits.sort((a, b) =>\n * compareByLength(a, b).concat(compareAlphabetically(a, b)).value\n * );\n *\n * console.log(fruits);\n * // Output: [ 'date', 'kiwi', 'apple', 'banana', 'cherry' ]\n * // Explanation:\n * // - 'date' has length 4\n * // - 'kiwi' has length 4\n * // - 'date' comes before 'kiwi' alphabetically\n * // - 'apple' has length 5\n * // - 'banana' and 'cherry' have length 6\n * // - 'banana' comes before 'cherry' alphabetically\n * // - They are sorted alphabetically among themselves\n */\n concat(other: Ordering): Ordering {\n return this.type !== \"Equal\" ? this : other;\n }\n\n /**\n * Converts a numeric comparison result into an `Ordering` instance.\n *\n * This static method interprets the sign of a number to determine the corresponding `Ordering`:\n *\n * - **`Ordering.LessThan`**: Returned if `num` is less than zero (`num < 0`).\n * - **`Ordering.Equal`**: Returned if `num` is exactly zero (`num === 0`).\n * - **`Ordering.GreaterThan`**: Returned if `num` is greater than zero (`num > 0`).\n *\n * **Important Note**: The input `num` must be a valid number and not `NaN`. If `num` is `NaN`, the method throws an error to prevent unexpected behavior.\n *\n * **Use Cases**:\n *\n * - Converting the result of numerical comparisons (e.g., `a - b`) into an `Ordering`.\n * - Integrating with APIs or functions that use the `Ordering` type for comparison logic.\n * - Enhancing type safety by avoiding the use of raw numeric comparison results.\n *\n * @static\n * @param {number} num - The number to convert into an `Ordering` (must not be `NaN`).\n * @returns {Ordering} The corresponding `Ordering` based on the sign of `num`.\n * @throws {Error} Throws an error if `num` is `NaN`.\n *\n * @example\n * // Example: Using Ordering.from with numerical comparisons\n * const result1 = Ordering.from(5 - 10); // Returns Ordering.LessThan\n * const result2 = Ordering.from(10 - 5); // Returns Ordering.GreaterThan\n * const result3 = Ordering.from(5 - 5); // Returns Ordering.Equal\n *\n * @example\n * // Example: Handling invalid input (NaN)\n * try {\n * const invalidResult = Ordering.from(NaN);\n * } catch (error) {\n * console.error(error.message); // Output: 'Cannot convert NaN to Ordering.'\n * }\n *\n * @example\n * // Example: Using Ordering.from in a custom comparator function\n * const compareNumbers = (a: number, b: number): Ordering => Ordering.from(a - b);\n *\n * const ordering = compareNumbers(15, 10);\n * console.log(ordering.type); // Output: 'GreaterThan'\n */\n static from(num: number): Ordering {\n if (isNaN(num)) {\n throw new Error(\"Cannot convert NaN to Ordering.\");\n }\n if (num < 0) return Ordering.LessThan;\n if (num > 0) return Ordering.GreaterThan;\n return Ordering.Equal;\n }\n\n /**\n * Creates a comparator function for items of type `A` by comparing their keys of type `B`,\n * which are obtained via a selector function. The comparison of the keys is performed using\n * a provided comparator function for type `B`.\n *\n * This static method is useful for creating comparator functions for complex data structures,\n * where you need to sort or compare items based on a specific property or derived value.\n *\n * **How It Works**:\n *\n * - The `selector` function extracts a key of type `B` from an item of type `A`.\n * - The `comparator` function compares two keys of type `B` and returns a numeric result.\n * - The returned comparator function takes two items of type `A`, extracts their keys using the `selector`,\n * compares the keys using the `comparator`, and converts the numeric result into an `Ordering` using `Ordering.from`.\n *\n * **Important Note**:\n *\n * - The `comparator` function should return a valid number (not `NaN`). If the result is `NaN`, an error is thrown.\n *\n * **Type Parameters**:\n *\n * - `A`: The type of the items to compare.\n * - `B`: The type of the keys extracted from the items.\n *\n * @static\n * @template A The type of the items to compare.\n * @template B The type of the keys to compare.\n * @param {(item: A) => B} selector - A function that selects the comparison key from an item of type `A`.\n * @param {(a: B, b: B) => number} comparator - A comparator function for keys of type `B` (should return a valid number, not `NaN`).\n * @returns {(a: A, b: A) => Ordering} A comparator function that takes two items of type `A` and returns an `Ordering`.\n * @throws {Error} Throws an error if the `comparator` function returns `NaN`.\n *\n * @example\n * // Example: Comparing users by age\n * interface User {\n * name: string;\n * age: number;\n * }\n *\n * const users: User[] = [\n * { name: 'Alice', age: 30 },\n * { name: 'Bob', age: 25 },\n * { name: 'Charlie', age: 35 },\n * ];\n *\n * const compareByAge = Ordering.comparing<User, number>(\n * user => user.age, // Selector function to extract the age\n * (a, b) => a - b // Comparator function for numbers\n * );\n *\n * // Using the comparator to sort the array\n * users.sort((a, b) => compareByAge(a, b).value);\n *\n * console.log(users);\n * // Output:\n * // [\n * // { name: 'Bob', age: 25 },\n * // { name: 'Alice', age: 30 },\n * // { name: 'Charlie', age: 35 },\n * // ]\n *\n * @example\n * // Example: Comparing strings by length\n * const strings = ['apple', 'banana', 'cherry', 'date'];\n *\n * const compareByLength = Ordering.comparing<string, number>(\n * str => str.length, // Selector function to get the length\n * (a, b) => a - b // Comparator function for numbers\n * );\n *\n * strings.sort((a, b) => compareByLength(a, b).value);\n *\n * console.log(strings);\n * // Output: ['date', 'apple', 'banana', 'cherry']\n *\n * @example\n * // Example: Comparing products by price, handling potential NaN values\n * interface Product {\n * name: string;\n * price: number;\n * }\n *\n * const products: Product[] = [\n * { name: 'Product A', price: 10 },\n * { name: 'Product B', price: NaN }, // Invalid price\n * { name: 'Product C', price: 5 },\n * ];\n *\n * const compareByPrice = Ordering.comparing<Product, number>(\n * product => product.price,\n * (a, b) => a - b\n * );\n *\n * try {\n * products.sort((a, b) => compareByPrice(a, b).value);\n * } catch (error) {\n * console.error(error.message); // Output: 'Comparator function returned NaN.'\n * }\n */\n static comparing<A, B>(selector: (item: A) => B, comparator: (a: B, b: B) => number): (a: A, b: A) => Ordering {\n return (a: A, b: A) => {\n const result = comparator(selector(a), selector(b));\n if (isNaN(result)) {\n throw new Error(\"Comparator function returned NaN.\");\n }\n return Ordering.from(result);\n };\n }\n\n /**\n * Creates a composite comparator function by combining multiple comparator functions.\n *\n * This static method allows you to chain multiple comparator functions, applying them sequentially to compare two items of type `A`. It returns the result of the first comparator that does not return `Equal`. If all comparators return `Equal`, the combined comparator returns `Equal`.\n *\n * **How It Works**:\n *\n * - The method accepts a variable number of comparator functions (`comparators`), each of which compares two items of type `A` and returns an `Ordering`.\n * - The returned comparator function takes two items `a` and `b`, and applies each comparator in the provided order.\n * - For each comparator, if the result is not `Equal`, it returns that `Ordering` immediately.\n * - If all comparators return `Equal`, it returns `Ordering.Equal`.\n *\n * **Use Cases**:\n *\n * - Useful when you need to compare items based on multiple criteria, proceeding to the next criterion only if previous comparisons are inconclusive (`Equal`).\n * - Helps in building complex sorting logic in a clean and readable manner.\n *\n * **Type Parameters**:\n *\n * - `A`: The type of the items to compare.\n *\n * @static\n * @template A The type of the items to compare.\n * @param {...Array<(a: A, b: A) => Ordering>} comparators - A variable number of comparator functions to be combined.\n * @returns {(a: A, b: A) => Ordering} A composite comparator function that applies each comparator in order.\n *\n * @example\n * // Example: Comparing users by last name, then first name\n * interface User {\n * firstName: string;\n * lastName: string;\n * age: number;\n * }\n *\n * const users: User[] = [\n * { firstName: 'John', lastName: 'Doe', age: 30 },\n * { firstName: 'Jane', lastName: 'Doe', age: 25 },\n * { firstName: 'Alice', lastName: 'Smith', age: 28 },\n * { firstName: 'Bob', lastName: 'Brown', age: 35 },\n * ];\n *\n * const compareByLastName = Ordering.comparing<User, string>(\n * user => user.lastName,\n * (a, b) => a.localeCompare(b)\n * );\n *\n * const compareByFirstName = Ordering.comparing<User, string>(\n * user => user.firstName,\n * (a, b) => a.localeCompare(b)\n * );\n *\n * const userComparator = Ordering.compareBy<User>(\n * compareByLastName,\n * compareByFirstName\n * );\n *\n * // Using the comparator to sort the array\n * users.sort((a, b) => userComparator(a, b).value);\n *\n * console.log(users);\n * // Output:\n * // [\n * // { firstName: 'Bob', lastName: 'Brown', age: 35 },\n * // { firstName: 'Jane', lastName: 'Doe', age: 25 },\n * // { firstName: 'John', lastName: 'Doe', age: 30 },\n * // { firstName: 'Alice', lastName: 'Smith', age: 28 },\n * // ]\n *\n * @example\n * // Example: Comparing products by category, then price\n * interface Product {\n * name: string;\n * category: string;\n * price: number;\n * }\n *\n * const products: Product[] = [\n * { name: 'Product A', category: 'Electronics', price: 99 },\n * { name: 'Product B', category: 'Clothing', price: 49 },\n * { name: 'Product C', category: 'Electronics', price: 199 },\n * { name: 'Product D', category: 'Clothing', price: 29 },\n * ];\n *\n * const compareByCategory = Ordering.comparing<Product, string>(\n * product => product.category,\n * (a, b) => a.localeCompare(b)\n * );\n *\n * const compareByPrice = Ordering.comparing<Product, number>(\n * product => product.price,\n * (a, b) => a - b\n * );\n *\n * const productComparator = Ordering.compareBy<Product>(\n * compareByCategory,\n * compareByPrice\n * );\n *\n * // Using the comparator to sort the array\n * products.sort((a, b) => productComparator(a, b).value);\n *\n * console.log(products);\n * // Output:\n * // [\n * // { name: 'Product D', category: 'Clothing', price: 29 },\n * // { name: 'Product B', category: 'Clothing', price: 49 },\n * // { name: 'Product A', category: 'Electronics', price: 99 },\n * // { name: 'Product C', category: 'Electronics', price: 199 },\n * // ]\n *\n * @example\n * // Example: Using compareBy with different types of comparators\n * const compareByLength = Ordering.comparing<string, number>(\n * str => str.length,\n * (a, b) => a - b\n * );\n *\n * const compareAlphabetically = Ordering.comparing<string, string>(\n * str => str,\n * (a, b) => a.localeCompare(b)\n * );\n *\n * const stringComparator = Ordering.compareBy<string>(\n * compareByLength,\n * compareAlphabetically\n * );\n *\n * const strings = ['apple', 'banana', 'cherry', 'date', 'fig'];\n *\n * strings.sort((a, b) => stringComparator(a, b).value);\n *\n * console.log(strings);\n * // Output: ['fig', 'date', 'apple', 'banana', 'cherry']\n *\n * // Explanation:\n * // - 'fig' has length 3\n * // - 'date' has length 4\n * // - 'apple', 'banana', and 'cherry' have length 5, sorted alphabetically\n */\n static compareBy<A>(...comparators: Array<(a: A, b: A) => Ordering>): (a: A, b: A) => Ordering {\n return (a: A, b: A) => {\n for (const comparator of comparators) {\n const result = comparator(a, b);\n if (result.type !== \"Equal\") {\n return result;\n }\n }\n return Ordering.Equal;\n };\n }\n}\n\n/**\n * Alias for `Ordering.LessThan`.\n *\n * Represents the `Ordering` where the first value is less than the second.\n *\n * @example\n * if (ordering === LT) {\n * console.log('First value is less than the second.');\n * }\n *\n * @see Ordering.LessThan\n */\nexport const LT = Ordering.LessThan;\n\n/**\n * Alias for `Ordering.Equal`.\n *\n * Represents the `Ordering` where the first value is equal to the second.\n *\n * @example\n * if (ordering === EQ) {\n * console.log('Values are equal.');\n * }\n *\n * @see Ordering.Equal\n */\nexport const EQ = Ordering.Equal;\n\n/**\n * Alias for `Ordering.GreaterThan`.\n *\n * Represents the `Ordering` where the first value is greater than the second.\n *\n * @example\n * if (ordering === GT) {\n * console.log('First value is greater than the second.');\n * }\n *\n * @see Ordering.GreaterThan\n */\nexport const GT = Ordering.GreaterThan;\n"],"mappings":"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"}
|