import { MacroContext, Op } from '@typesugar/core';
export { FlatMap, flatMapArray, flatMapAsyncIterable, flatMapIterable, flatMapPromise, getFlatMap, hasFlatMap, registerFlatMap } from './flatmap.js';
import * as ts from 'typescript';
import { B as BindStep, M as MapStep } from '../comprehension-utils-CrcEKA_W.js';
import '@typesugar/macros';

/**
 * ParCombine Typeclass
 *
 * Defines how to combine multiple independent effects of the same type constructor
 * into a single effect. Used by the `par:/yield:` macro for parallel applicative
 * comprehensions.
 *
 * ## Instances
 *
 * Built-in instances:
 * - Promise — Promise.all + .then()
 * - AsyncIterable — Array.fromAsync + Promise.all + .then()
 * - Array — cartesian product
 * - Iterable — collect to arrays, then cartesian product
 *
 * ## Usage with par:/yield:
 *
 * ```typescript
 * par: {
 *   user   << fetchUser(id)
 *   config << loadConfig()
 * }
 * yield: ({ user, config })
 * // Promise: Promise.all([...]).then(([user, config]) => ({ user, config }))
 * ```
 *
 * @internal
 */

/**
 * ParCombine typeclass — parallel combination for type constructors.
 *
 * Defines how to combine multiple independent effects into a single effect
 * containing all results. Used by par:/yield: macro.
 *
 * @macro-only — Uses `unknown` because the macro handles type safety at
 * the call site through compile-time code generation.
 */
interface ParCombine<F> {
    /**
     * Combine multiple independent effects into a single effect of an array.
     */
    all(effects: readonly unknown[]): unknown;
    /**
     * Map/transform the combined result.
     */
    map(combined: unknown, f: (results: unknown[]) => unknown): unknown;
}
interface _PromiseTag {
    readonly _tag: "Promise";
}
interface _AsyncIterableTag {
    readonly _tag: "AsyncIterable";
}
interface _ArrayTag {
    readonly _tag: "Array";
}
interface _IterableTag {
    readonly _tag: "Iterable";
}
declare const parCombinePromise: ParCombine<_PromiseTag>;
declare const parCombineAsyncIterable: ParCombine<_AsyncIterableTag>;
declare const parCombineArray: ParCombine<_ArrayTag>;
declare const parCombineIterable: ParCombine<_IterableTag>;
type ParCombineBuilder = (ctx: MacroContext, steps: (BindStep | MapStep)[], returnExpr: ts.Expression) => ts.Expression;
/**
 * Get a ParCombine instance by type constructor name.
 *
 * @deprecated Use findInstance("ParCombine", name) from @typesugar/macros for new code.
 * This function is maintained for backward compatibility.
 */
declare function getParCombine(name: string): ParCombine<unknown> | undefined;
/**
 * Get the zero-cost builder for a type constructor, if registered.
 *
 * @deprecated Use getParCombineBuilderFromRegistry(name) from @typesugar/macros for new code.
 * This function is maintained for backward compatibility.
 */
declare function getParCombineBuilder(name: string): ParCombineBuilder | undefined;
/**
 * Register a ParCombine instance for a type constructor.
 * Provide a builder for zero-cost macro expansion, or omit to use runtime dispatch.
 *
 * @deprecated Use @instance decorator or registerInstanceWithMeta() + registerParCombineBuilder()
 * from @typesugar/macros for new code. This function is maintained for backward compatibility.
 */
declare function registerParCombine<F>(name: string, instance: ParCombine<F>, builder?: ParCombineBuilder): void;

/**
 * Generic Numeric Operations
 *
 * Derived operations that work for ANY type with a Numeric, Integral, or Fractional instance.
 * All functions use dictionary-passing style for zero-cost specialization via `specialize()`.
 *
 * Note: Functions that might conflict with concrete versions in extensions/number.ts
 * are named with `With` suffix (e.g., `gcdWith`, `lerpWith`) to indicate they take
 * a typeclass instance parameter.
 *
 * @example
 * ```typescript
 * import { sum, product, pow, gcdWith } from "@typesugar/std";
 * import { numericNumber, integralNumber } from "@typesugar/std";
 *
 * // Works for any Numeric<A>
 * sum([1, 2, 3, 4, 5], numericNumber); // 15
 * product([1, 2, 3, 4], numericNumber); // 24
 * pow(2, 10, numericNumber); // 1024
 *
 * // Works for any Integral<A>
 * gcdWith(48, 18, numericNumber, integralNumber); // 6
 * ```
 */

/**
 * Sum all elements in an iterable.
 *
 * @param xs - Iterable of values to sum
 * @param N - Numeric instance for type A
 * @returns The sum of all elements, or zero() if empty
 */
declare function sum<A>(xs: Iterable<A>, N: Numeric<A>): A;
/**
 * Multiply all elements in an iterable.
 *
 * @param xs - Iterable of values to multiply
 * @param N - Numeric instance for type A
 * @returns The product of all elements, or one() if empty
 */
declare function product<A>(xs: Iterable<A>, N: Numeric<A>): A;
/**
 * Raise base to a non-negative integer power using repeated squaring.
 * O(log n) multiplications.
 *
 * @param base - The base value
 * @param exp - Non-negative integer exponent
 * @param N - Numeric instance for type A
 * @returns base^exp
 * @throws RangeError if exp is negative
 */
declare function pow<A>(base: A, exp: number, N: Numeric<A>): A;
/**
 * Raise base to an integer power (can be negative for Fractional types).
 *
 * @param base - The base value
 * @param exp - Integer exponent (can be negative)
 * @param N - Numeric instance for type A
 * @param F - Fractional instance for type A (needed for negative exponents)
 * @returns base^exp
 */
declare function powFrac<A>(base: A, exp: number, N: Numeric<A>, F: Fractional<A>): A;
/**
 * Greatest common divisor using Euclidean algorithm.
 * Generic version that works for any Integral type.
 *
 * @param a - First value
 * @param b - Second value
 * @param N - Numeric instance for type A
 * @param I - Integral instance for type A
 * @returns The GCD of a and b
 */
declare function gcdWith<A>(a: A, b: A, N: Numeric<A>, I: Integral<A>): A;
/**
 * Least common multiple.
 * Generic version that works for any Integral type.
 *
 * @param a - First value
 * @param b - Second value
 * @param N - Numeric instance for type A
 * @param I - Integral instance for type A
 * @returns The LCM of a and b
 */
declare function lcmWith<A>(a: A, b: A, N: Numeric<A>, I: Integral<A>): A;
/**
 * Clamp a value to a range [lo, hi].
 * Generic version that works for any Ord type.
 *
 * @param x - Value to clamp
 * @param lo - Lower bound
 * @param hi - Upper bound
 * @param O - Ord instance for type A
 * @returns x clamped to [lo, hi]
 */
declare function clampWith<A>(x: A, lo: A, hi: A, O: Ord<A>): A;
/**
 * Return the minimum of two values.
 *
 * @param a - First value
 * @param b - Second value
 * @param O - Ord instance for type A
 * @returns The smaller of a and b
 */
declare function min<A>(a: A, b: A, O: Ord<A>): A;
/**
 * Return the maximum of two values.
 *
 * @param a - First value
 * @param b - Second value
 * @param O - Ord instance for type A
 * @returns The larger of a and b
 */
declare function max<A>(a: A, b: A, O: Ord<A>): A;
/**
 * Return the minimum element of an iterable.
 *
 * @param xs - Non-empty iterable
 * @param O - Ord instance for type A
 * @returns The minimum element
 * @throws Error if iterable is empty
 */
declare function minBy<A>(xs: Iterable<A>, O: Ord<A>): A;
/**
 * Return the maximum element of an iterable.
 *
 * @param xs - Non-empty iterable
 * @param O - Ord instance for type A
 * @returns The maximum element
 * @throws Error if iterable is empty
 */
declare function maxBy<A>(xs: Iterable<A>, O: Ord<A>): A;
/**
 * Linear interpolation between two values.
 * Generic version that works for any Fractional type.
 *
 * @param a - Start value (t=0)
 * @param b - End value (t=1)
 * @param t - Interpolation parameter (0 to 1)
 * @param N - Numeric instance for type A
 * @param F - Fractional instance for type A
 * @returns a + t * (b - a)
 */
declare function lerpWith<A>(a: A, b: A, t: A, N: Numeric<A>, F: Fractional<A>): A;
/**
 * Inverse linear interpolation: find t such that lerp(a, b, t) = value.
 * Generic version that works for any Fractional type.
 *
 * @param a - Start value (t=0)
 * @param b - End value (t=1)
 * @param value - The value to find t for
 * @param N - Numeric instance for type A
 * @param F - Fractional instance for type A
 * @returns t such that lerp(a, b, t) ≈ value
 */
declare function inverseLerpWith<A>(a: A, b: A, value: A, N: Numeric<A>, F: Fractional<A>): A;
/**
 * Convert a bigint to any Numeric type.
 *
 * @param n - Integer value
 * @param N - Numeric instance for type A
 * @returns The value as type A
 */
declare function fromInteger<A>(n: bigint, N: Numeric<A>): A;
/**
 * Convert an integer to any Numeric type.
 *
 * @param n - Integer value
 * @param N - Numeric instance for type A
 * @returns The value as type A
 */
declare function fromInt<A>(n: number, N: Numeric<A>): A;

/**
 * Standard Typeclasses
 *
 * A comprehensive set of typeclasses drawing from the best of:
 * - Haskell (Bounded, Enum, Num, Integral, Fractional, Read, Show)
 * - Scala 3 (Ordering, Numeric, Conversion, CanEqual)
 * - Rust (Default, Clone, Copy, Display, FromStr, Into/From, Iterator)
 * - Kotlin (Comparable, ClosedRange, Iterable, Grouping)
 * - Swift (Codable, Hashable, Identifiable, CustomStringConvertible)
 *
 * All typeclasses follow the @typeclass pattern and support:
 * - Auto-derivation via @deriving
 * - Extension methods via the typeclass system
 * - Zero-cost specialization via inlining
 * - Operator overloading via Op<> annotations
 */

/**
 * Eq typeclass - equality comparison with operator support.
 *
 * Laws:
 * - Reflexivity: `equals(x, x) === true`
 * - Symmetry: `equals(x, y) === equals(y, x)`
 * - Transitivity: `equals(x, y) && equals(y, z) => equals(x, z)`
 *
 * Operators dispatch via Op<> annotations:
 * - `a === b` → `Eq.equals(a, b)`
 * - `a !== b` → `Eq.notEquals(a, b)`
 */
interface Eq<A> {
    equals(a: A, b: A): boolean & Op<"===">;
    notEquals(a: A, b: A): boolean & Op<"!==">;
}
declare const eqNumber: Eq<number>;
declare const eqBigInt: Eq<bigint>;
declare const eqString: Eq<string>;
declare const eqBoolean: Eq<boolean>;
declare const eqDate: Eq<Date>;
/**
 * Create an Eq instance from a custom equality function.
 */
declare function makeEq<A>(eq: (a: A, b: A) => boolean): Eq<A>;
/**
 * Create an Eq instance by mapping to a comparable value.
 */
declare function eqBy<A, B>(f: (a: A) => B, E?: Eq<B>): Eq<A>;
/**
 * Eq using strict equality (===).
 */
declare function eqStrict<A>(): Eq<A>;
/**
 * Eq for arrays (element-wise comparison).
 */
declare function eqArray<A>(E: Eq<A>): Eq<A[]>;
/**
 * Ordering result type.
 */
type Ordering = -1 | 0 | 1;
declare const LT: Ordering;
declare const EQ_ORD: Ordering;
declare const GT: Ordering;
/**
 * Ord typeclass - total ordering with operator support.
 *
 * Laws (in addition to Eq laws):
 * - Antisymmetry: `compare(x, y) <= 0 && compare(y, x) <= 0 => equals(x, y)`
 * - Transitivity: `compare(x, y) <= 0 && compare(y, z) <= 0 => compare(x, z) <= 0`
 * - Totality: `compare(x, y) <= 0 || compare(y, x) <= 0`
 *
 * Operators dispatch via Op<> annotations:
 * - `a < b`  → `Ord.lessThan(a, b)`
 * - `a <= b` → `Ord.lessThanOrEqual(a, b)`
 * - `a > b`  → `Ord.greaterThan(a, b)`
 * - `a >= b` → `Ord.greaterThanOrEqual(a, b)`
 */
interface Ord<A> extends Eq<A> {
    compare(a: A, b: A): Ordering;
    lessThan(a: A, b: A): boolean & Op<"<">;
    lessThanOrEqual(a: A, b: A): boolean & Op<"<=">;
    greaterThan(a: A, b: A): boolean & Op<">">;
    greaterThanOrEqual(a: A, b: A): boolean & Op<">=">;
}
declare const ordNumber: Ord<number>;
declare const ordBigInt: Ord<bigint>;
declare const ordString: Ord<string>;
declare const ordBoolean: Ord<boolean>;
declare const ordDate: Ord<Date>;
/**
 * Create an Ord instance from a compare function.
 */
declare function makeOrd<A>(compare: (a: A, b: A) => Ordering): Ord<A>;
/**
 * Create an Ord instance by mapping to a comparable value.
 */
declare function ordBy<A, B>(f: (a: A) => B, O: Ord<B>): Ord<A>;
/**
 * Reverse an Ord instance.
 */
declare function reverseOrd<A>(O: Ord<A>): Ord<A>;
/**
 * Ord for arrays (lexicographic comparison).
 */
declare function ordArray<A>(O: Ord<A>): Ord<A[]>;
/**
 * Semigroup typeclass - types with an associative combine operation.
 *
 * Law:
 * - Associativity: `combine(combine(a, b), c) === combine(a, combine(b, c))`
 *
 * Operators dispatch via Op<> annotations:
 * - `a + b` → `Semigroup.combine(a, b)` (for additive semigroups)
 */
interface Semigroup<A> {
    combine(a: A, b: A): A & Op<"+">;
}
declare const semigroupString: Semigroup<string>;
declare const semigroupNumber: Semigroup<number>;
declare const semigroupBigInt: Semigroup<bigint>;
/**
 * Semigroup for arrays (concatenation).
 */
declare function semigroupArray<A>(): Semigroup<A[]>;
/**
 * Monoid typeclass - Semigroup with an identity element.
 *
 * Laws (in addition to Semigroup laws):
 * - Left identity: `combine(empty(), a) === a`
 * - Right identity: `combine(a, empty()) === a`
 */
interface Monoid<A> extends Semigroup<A> {
    empty(): A;
}
declare const monoidString: Monoid<string>;
declare const monoidNumber: Monoid<number>;
declare const monoidBigInt: Monoid<bigint>;
/**
 * Monoid for arrays (concatenation with empty array).
 */
declare function monoidArray<A>(): Monoid<A[]>;

/**
 * Bounded typeclass - types with minimum and maximum values.
 * Use `registerStdInstances()` macro to enable summon<Bounded<T>>() resolution.
 */
interface Bounded<A> {
    minBound(): A;
    maxBound(): A;
}
declare const boundedNumber: Bounded<number>;
declare const boundedBigInt: Bounded<bigint>;
declare const boundedBoolean: Bounded<boolean>;
declare const boundedString: Bounded<string>;
/**
 * Enum typeclass - types with successors/predecessors, convertible to/from integers.
 * Use `registerStdInstances()` macro to enable summon<Enum<T>>() resolution.
 */
interface Enum<A> {
    succ(a: A): A;
    pred(a: A): A;
    toEnum(n: number): A;
    fromEnum(a: A): number;
}
declare const enumNumber: Enum<number>;
declare const enumBoolean: Enum<boolean>;
declare const enumString: Enum<string>;
/**
 * Numeric typeclass - types supporting basic arithmetic operations.
 *
 * This is the Ring abstraction: add, sub, mul with identity elements.
 * Use `registerStdInstances()` macro to enable summon<Numeric<T>>() resolution.
 *
 * Operators dispatch via Op<> annotations:
 * - `a + b` → `Numeric.add(a, b)`
 * - `a - b` → `Numeric.sub(a, b)`
 * - `a * b` → `Numeric.mul(a, b)`
 */
interface Numeric<A> {
    add(a: A, b: A): A & Op<"+">;
    sub(a: A, b: A): A & Op<"-">;
    mul(a: A, b: A): A & Op<"*">;
    negate(a: A): A;
    abs(a: A): A;
    signum(a: A): A;
    fromNumber(n: number): A;
    toNumber(a: A): number;
    zero(): A;
    one(): A;
}
declare const numericNumber: Numeric<number>;
declare const numericBigInt: Numeric<bigint>;
/**
 * Integral typeclass - integer-like types supporting division and modulo.
 *
 * This is the Euclidean Ring abstraction.
 *
 * Operators dispatch via Op<> annotations (for integer types):
 * - `a / b` → `Integral.div(a, b)` (floor division)
 * - `a % b` → `Integral.mod(a, b)` (modulo)
 */
interface Integral<A> {
    div(a: A, b: A): A & Op<"/">;
    mod(a: A, b: A): A & Op<"%">;
    divMod(a: A, b: A): [A, A];
    quot(a: A, b: A): A;
    rem(a: A, b: A): A;
    toInteger(a: A): bigint;
}
declare const integralNumber: Integral<number>;
declare const integralBigInt: Integral<bigint>;
/**
 * Fractional typeclass - types supporting real division.
 *
 * This is the Field abstraction (for fractional/floating types).
 *
 * Operators dispatch via Op<> annotations (for fractional types):
 * - `a / b` → `Fractional.div(a, b)` (true division)
 */
interface Fractional<A> {
    div(a: A, b: A): A & Op<"/">;
    recip(a: A): A;
    fromRational(num: number, den: number): A;
}
declare const fractionalNumber: Fractional<number>;
interface Floating<A> {
    pi(): A;
    exp(a: A): A;
    log(a: A): A;
    sqrt(a: A): A;
    pow(a: A, b: A): A;
    sin(a: A): A;
    cos(a: A): A;
    tan(a: A): A;
    asin(a: A): A;
    acos(a: A): A;
    atan(a: A): A;
    atan2(a: A, b: A): A;
    sinh(a: A): A;
    cosh(a: A): A;
    tanh(a: A): A;
}
declare const floatingNumber: Floating<number>;
type ParseResult<A> = {
    ok: true;
    value: A;
    rest: string;
} | {
    ok: false;
    error: string;
};
interface Parseable<A> {
    parse(s: string): ParseResult<A>;
}
declare const parseableNumber: Parseable<number>;
declare const parseableBoolean: Parseable<boolean>;
declare const parseableBigInt: Parseable<bigint>;
interface Printable<A> {
    display(a: A): string;
}
declare const printableNumber: Printable<number>;
declare const printableString: Printable<string>;
declare const printableBoolean: Printable<boolean>;
declare const printableDate: Printable<Date>;
interface Coercible<A, B> {
    coerce(a: A): B;
}
declare const numberToString: Coercible<number, string>;
declare const stringToNumber: Coercible<string, number>;
declare const numberToBigInt: Coercible<number, bigint>;
declare const bigIntToNumber: Coercible<bigint, number>;
declare const numberToBoolean: Coercible<number, boolean>;
declare const booleanToNumber: Coercible<boolean, number>;
declare const stringToBoolean: Coercible<string, boolean>;
declare const dateToNumber: Coercible<Date, number>;
declare const numberToDate: Coercible<number, Date>;
interface Defaultable<A> {
    defaultValue(): A;
}
declare const defaultNumber: Defaultable<number>;
declare const defaultString: Defaultable<string>;
declare const defaultBoolean: Defaultable<boolean>;
declare const defaultBigInt: Defaultable<bigint>;
declare function defaultArray<A>(): Defaultable<A[]>;
declare function defaultMap<K, V>(): Defaultable<Map<K, V>>;
declare function defaultSet<A>(): Defaultable<Set<A>>;
declare const defaultDate: Defaultable<Date>;
interface Copyable<A> {
    copy(a: A): A;
}
declare const copyableNumber: Copyable<number>;
declare const copyableString: Copyable<string>;
declare const copyableBoolean: Copyable<boolean>;
declare const copyableBigInt: Copyable<bigint>;
declare const copyableDate: Copyable<Date>;
declare function copyableArray<A>(inner: Copyable<A>): Copyable<A[]>;
declare function copyableMap<K, V>(innerK: Copyable<K>, innerV: Copyable<V>): Copyable<Map<K, V>>;
declare function copyableSet<A>(inner: Copyable<A>): Copyable<Set<A>>;
interface Sized<A> {
    size(a: A): number;
    isEmpty(a: A): boolean;
}
declare const sizedString: Sized<string>;
declare function sizedArray<A>(): Sized<A[]>;
declare function sizedMap<K, V>(): Sized<Map<K, V>>;
declare function sizedSet<A>(): Sized<Set<A>>;
interface Identifiable<A, Id = string> {
    id(a: A): Id;
}
interface Reducible<F> {
    reduceLeft<A>(fa: F, f: (acc: A, a: A) => A): A;
    reduceRight<A>(fa: F, f: (a: A, acc: A) => A): A;
}
interface Zippable<F> {
    zip<A, B>(fa: F, fb: F): F;
    zipWith<A, B, C>(fa: F, fb: F, f: (a: A, b: B) => C): F;
}
interface Splittable<F> {
    splitAt<A>(fa: F, n: number): [F, F];
    partition<A>(fa: F, pred: (a: A) => boolean): [F, F];
    chunked<A>(fa: F, size: number): F[];
}
interface Searchable<F> {
    find<A>(fa: F, pred: (a: A) => boolean): A | undefined;
    contains<A>(fa: F, elem: A): boolean;
    indexOf<A>(fa: F, elem: A): number;
}
/**
 * Group typeclass - a Monoid with an inverse operation.
 *
 * Laws:
 * - All Monoid laws (associativity, identity)
 * - Left inverse: `combine(invert(a), a) === empty()`
 * - Right inverse: `combine(a, invert(a)) === empty()`
 *
 * @example
 * ```typescript
 * const additiveGroup: Group<number> = {
 *   empty: () => 0,
 *   combine: (a, b) => a + b,
 *   invert: (a) => -a,
 * };
 * ```
 */
interface Group<A> {
    /** The identity element */
    empty(): A;
    /** Associative binary operation */
    combine(a: A, b: A): A & Op<"+">;
    /** Inverse operation: combine(invert(a), a) === empty() */
    invert(a: A): A;
}
/** Additive group for numbers (identity: 0, operation: +, inverse: negation) */
declare const groupNumber: Group<number>;
/** Additive group for bigint */
declare const groupBigInt: Group<bigint>;

export { type Bounded, type Coercible, type Copyable, type Defaultable, EQ_ORD, type Enum, type Eq, type Floating, type Fractional, GT, type Group, type Identifiable, type Integral, LT, type Monoid, type Numeric, type Ord, type Ordering, type ParCombine, type ParCombineBuilder, type ParseResult, type Parseable, type Printable, type Reducible, type Searchable, type Semigroup, type Sized, type Splittable, type Zippable, bigIntToNumber, booleanToNumber, boundedBigInt, boundedBoolean, boundedNumber, boundedString, clampWith, copyableArray, copyableBigInt, copyableBoolean, copyableDate, copyableMap, copyableNumber, copyableSet, copyableString, dateToNumber, defaultArray, defaultBigInt, defaultBoolean, defaultDate, defaultMap, defaultNumber, defaultSet, defaultString, enumBoolean, enumNumber, enumString, eqArray, eqBigInt, eqBoolean, eqBy, eqDate, eqNumber, eqStrict, eqString, floatingNumber, fractionalNumber, fromInt, fromInteger, gcdWith, getParCombine, getParCombineBuilder, groupBigInt, groupNumber, integralBigInt, integralNumber, inverseLerpWith, lcmWith, lerpWith, makeEq, makeOrd, max, maxBy, min, minBy, monoidArray, monoidBigInt, monoidNumber, monoidString, numberToBigInt, numberToBoolean, numberToDate, numberToString, numericBigInt, numericNumber, ordArray, ordBigInt, ordBoolean, ordBy, ordDate, ordNumber, ordString, parCombineArray, parCombineAsyncIterable, parCombineIterable, parCombinePromise, parseableBigInt, parseableBoolean, parseableNumber, pow, powFrac, printableBoolean, printableDate, printableNumber, printableString, product, registerParCombine, reverseOrd, semigroupArray, semigroupBigInt, semigroupNumber, semigroupString, sizedArray, sizedMap, sizedSet, sizedString, stringToBoolean, stringToNumber, sum };
