export { B as BindStep, C as ComprehensionStep, G as GuardStep, M as MapStep, c as collectReferencedIdentifiers, a as createArrowFn, b as createIIFE, d as createMethodCall, e as extractReturnExpr, i as inferTypeConstructor } from '../comprehension-utils-CrcEKA_W.js';
import * as _typesugar_core from '@typesugar/core';
import { LabeledBlockMacro, ExpressionMacro } from '@typesugar/core';
import 'typescript';

/**
 * let:/yield: Labeled Block Macro
 *
 * Generic do-notation style syntax that works with any type that has a
 * FlatMap instance. Desugars `let: { x << expr }` blocks into flatMap chains.
 *
 * ## Syntax
 *
 * ```typescript
 * let: {
 *   x << expr1           // Monadic bind: flatMap
 *   y = x * 2            // Pure map: inline computation
 *   _ << sideEffect()    // Discard: bind but ignore result
 *   z << expr2 || alt    // orElse: fallback on failure
 *   if (condition) {}    // Guard: short-circuit on false
 * }
 * yield: { resultExpr }
 * ```
 *
 * ## Examples
 *
 * ```typescript
 * // With Array
 * let: {
 *   x << [1, 2, 3]
 *   y << [x * 10, x * 20]
 * }
 * yield: ({ x, y })
 * // Compiles to: [1,2,3].flatMap(x => [x*10, x*20].map(y => ({ x, y })))
 *
 * // With Promise
 * let: {
 *   user << fetchUser(id)
 *   posts << fetchPosts(user.id)
 * }
 * yield: ({ user, posts })
 * // Compiles to: fetchUser(id).then(user => fetchPosts(user.id).then(posts => ({ user, posts })))
 *
 * // With guards and orElse
 * let: {
 *   x << someOption
 *   if (x > 0) {}           // Guards: short-circuit if false
 *   y << getY() || default  // orElse: fallback on failure
 * }
 * yield: (x + y)
 *
 * // Implicit yield (returns last binding)
 * let: {
 *   x << Some(42)
 * }
 * // Returns Some(42) directly
 * ```
 *
 * ## How it works
 *
 * 1. The macro parses steps from the `let:` block (binds, maps, guards)
 * 2. It infers the type constructor from the first bind's expression
 * 3. It looks up the FlatMap instance for that type constructor
 * 4. It generates a chain: flatMap for intermediate binds, map for the last
 *
 * ## Registering custom types
 *
 * ```typescript
 * import { registerFlatMap } from "@typesugar/std/typeclasses/flatmap";
 *
 * registerFlatMap("MyType", {
 *   map: (fa, f) => fa.map(f),
 *   flatMap: (fa, f) => fa.flatMap(f),
 * });
 * ```
 */

/**
 * The let:/yield: macro transforms labeled block syntax into FlatMap chains.
 *
 * It resolves the FlatMap instance based on the type of the first binding,
 * then generates appropriate map/flatMap calls.
 */
declare const letYieldMacro: LabeledBlockMacro;
/**
 * Register the let:/yield: macro with the global registry.
 */
declare function registerLetYield(): void;

/**
 * par:/yield: Labeled Block Macro
 *
 * Applicative (parallel) comprehension syntax. Unlike monadic `let:/yield:`,
 * all bindings in `par:` must be independent — no binding may reference a
 * previous binding's value.
 *
 * ## Syntax
 *
 * ```typescript
 * par: {
 *   a << expr1
 *   b << expr2
 *   c << expr3
 * }
 * yield: { f(a, b, c) }
 * ```
 *
 * ## Why use par: instead of let:?
 *
 * 1. **Parallel execution**: For Promises, `par:` emits `Promise.all([...])`,
 *    executing all effects concurrently. `let:` chains them sequentially.
 *
 * 2. **Error accumulation**: For Validation types, `par:` accumulates ALL errors
 *    from all bindings. `let:` short-circuits on the first error.
 *
 * 3. **Static independence check**: The macro validates at compile time that
 *    no binding depends on a previous binding, catching bugs early.
 *
 * ## Examples
 *
 * ```typescript
 * // Parallel Promises with Promise.all
 * par: {
 *   user   << fetchUser(id)
 *   config << loadConfig()
 *   posts  << fetchPosts(postId)
 * }
 * yield: ({ user, config, posts })
 * // Compiles to: Promise.all([fetchUser(id), loadConfig(), fetchPosts(postId)])
 * //                .then(([user, config, posts]) => ({ user, config, posts }))
 *
 * // Applicative combination with .map()/.ap()
 * par: {
 *   name << validateName(input.name)
 *   age  << validateAge(input.age)
 * }
 * yield: ({ name, age })
 * // Compiles to: validateName(input.name)
 * //                .map(name => age => ({ name, age }))
 * //                .ap(validateAge(input.age))
 *
 * // With pure map steps (IIFEs)
 * par: {
 *   a << Some(10)
 *   b << Some(20)
 *   c = 100  // pure computation
 * }
 * yield: (a + b + c)
 * // c is inlined as an IIFE around the yield expression
 * ```
 *
 * ## Restrictions
 *
 * - **No guards**: `if (cond) {}` is not allowed — applicative context
 *   doesn't support short-circuiting.
 * - **No orElse**: `<< expr || alt` is not allowed — use `let:` for fallbacks.
 * - **Independence required**: Bindings cannot reference previous bindings.
 *
 * ## How it works
 *
 * 1. The macro parses bind and map steps from the `par:` block
 * 2. It validates that no step references a previous step's binding
 * 3. It infers the type constructor from the first bind's expression
 * 4. For Promises, it emits `Promise.all([...]).then(([a, b, c]) => expr)`
 * 5. For other types, it emits `fa.map(a => b => c => expr).ap(fb).ap(fc)`
 */

/**
 * The par:/yield: macro transforms labeled block syntax into applicative chains.
 *
 * For Promises, emits Promise.all for parallel execution.
 * For other types, emits .map().ap().ap() chains.
 */
declare const parYieldMacro: LabeledBlockMacro;
/**
 * Register the par:/yield: macro with the global registry.
 */
declare function registerParYield(): void;

/**
 * Zero-Cost Exhaustive Pattern Matching
 *
 * A unified match() macro providing Scala-quality pattern matching that compiles
 * to optimized decision trees. Supports discriminated unions with destructuring,
 * literal dispatch, guard predicates, OR patterns, type patterns, and array
 * helpers — all with compile-time exhaustiveness checking and zero runtime overhead.
 *
 * ## Compilation Strategies
 *
 * | Pattern Kind          | Arms ≤ 6           | Arms > 6                 |
 * |-----------------------|---------------------|--------------------------|
 * | Discriminated union   | Ternary chain       | IIFE + switch statement  |
 * | String literals       | Ternary chain       | IIFE + switch statement  |
 * | Integer literals      | Ternary chain       | Binary search tree       |
 * | Dense integer range   | Ternary chain       | IIFE + switch (V8 jump)  |
 * | Guard predicates      | Ternary chain       | Ternary chain            |
 *
 * Binary search gives O(log n) comparisons for sparse integers vs O(n) linear.
 * Switch statements let V8 apply its own optimizations (hash tables, jump tables).
 *
 * @example
 * ```typescript
 * import { match, when, otherwise, isType, P } from "@typesugar/std";
 *
 * // Discriminated union with destructuring
 * type Shape =
 *   | { kind: "circle"; radius: number }
 *   | { kind: "square"; side: number }
 *   | { kind: "triangle"; base: number; height: number };
 *
 * const area = match(shape, {
 *   circle: ({ radius }) => Math.PI * radius ** 2,
 *   square: ({ side }) => side ** 2,
 *   triangle: ({ base, height }) => 0.5 * base * height,
 * });
 *
 * // OR patterns — pipe-separated keys share a handler
 * const flat = match(shape, {
 *   "circle|square": (s) => "flat shape",
 *   triangle: (s) => "angled shape",
 * });
 * // Compiles to: (kind === "circle" || kind === "square") ? handler : ...
 *
 * // Note: If your discriminant value literally contains `|`, use quoted key names
 * // and a separate handler for each variant. See Finding #7 in FINDINGS.md.
 *
 * // Literal dispatch with compile-time exhaustiveness
 * const msg = match(statusCode, {
 *   200: () => "OK",
 *   404: () => "Not Found",
 *   _: (code) => `Unknown: ${code}`,
 * });
 *
 * // Type patterns — isType<T>() generates optimal type guards
 * const desc = match(value, [
 *   when(isType("string"), s => `str: ${s}`),
 *   when(isType("number"), n => n.toFixed(2)),
 *   otherwise(() => "other"),
 * ]);
 *
 * // Array pattern helpers
 * const result = match(list, [
 *   when(P.empty, () => "empty"),
 *   when(P.length(1), ([x]) => `one: ${x}`),
 *   when(P.minLength(2), ([a, b]) => `starts: ${a}, ${b}`),
 *   otherwise(() => "default"),
 * ]);
 *
 * // Guard-based matching
 * const category = match(age, [
 *   when(n => n < 13, () => "child"),
 *   when(n => n < 18, () => "teen"),
 *   otherwise(() => "adult"),
 * ]);
 * ```
 */
/** Extracts discriminant literal values from a union type */
type DiscriminantOf<T, K extends keyof T> = T extends Record<K, infer V> ? (V extends string | number | boolean ? V : never) : never;
/** Handler map for discriminated union matching — each handler receives the narrowed variant */
type DiscriminantHandlers<T, K extends keyof T, R> = {
    [V in DiscriminantOf<T, K>]: (value: Extract<T, Record<K, V>>) => R;
} & {
    _?: (value: T) => R;
};
/** Handler map for literal value matching */
type LiteralHandlers<T extends string | number, R> = {
    [K in T]?: (value: K) => R;
} & {
    _?: (value: T) => R;
};
/** A guard arm produced by when() or otherwise() */
interface GuardArm<T, R> {
    readonly predicate: (value: T) => boolean;
    readonly handler: (value: T) => R;
}
/** Create a guard arm — matches when predicate returns true */
declare function when<T, R>(predicate: (value: T) => boolean, handler: (value: T) => R): GuardArm<T, R>;
/** Create a catch-all guard arm — always matches */
declare function otherwise<T, R>(handler: (value: T) => R): GuardArm<T, R>;
type PrimitiveTypeName = "string" | "number" | "boolean" | "bigint" | "symbol" | "undefined" | "function";
/**
 * Create a type guard predicate for use in match() guard arms.
 *
 * For primitives: generates `typeof x === "..."` checks.
 * For classes: pass the constructor directly for `instanceof` checks.
 * For null: use `isType("null")`.
 *
 * @example
 * ```typescript
 * match(value, [
 *   when(isType("string"), s => s.length),
 *   when(isType("number"), n => n.toFixed(2)),
 *   when(isType("null"), () => "nothing"),
 *   when(isType(Date), d => d.toISOString()),
 *   otherwise(() => "unknown"),
 * ]);
 * ```
 */
declare function isType(typeName: PrimitiveTypeName | "null" | "object"): (value: unknown) => boolean;
declare function isType<T>(ctor: new (...args: any[]) => T): (value: unknown) => value is T;
/**
 * Pattern helpers for array/tuple matching in guard arms.
 *
 * These are recognized by the match macro and compiled to optimal checks.
 * At runtime they work as regular predicates.
 *
 * @example
 * ```typescript
 * match(list, [
 *   when(P.empty, () => "empty list"),
 *   when(P.length(1), ([x]) => `singleton: ${x}`),
 *   when(P.length(2), ([a, b]) => `pair: ${a}, ${b}`),
 *   when(P.minLength(3), ([a, b, c, ...rest]) => `3+`),
 *   when(P.head(x => x > 0), ([pos, ...rest]) => `starts positive`),
 *   otherwise(() => "default"),
 * ]);
 * ```
 */
declare const P: {
    /**
     * Matches empty arrays: `arr.length === 0`
     *
     * Note: This also works on strings since strings have a `.length` property.
     * Using `P.empty` on a string will return true for empty strings `""`.
     * This is intentional - any value with `length === 0` matches.
     * See Finding #6 in FINDINGS.md.
     */
    readonly empty: (arr: readonly unknown[]) => boolean;
    /** Matches null or undefined */
    readonly nil: (value: unknown) => value is null | undefined;
    /** Matches non-null, non-undefined */
    readonly defined: (value: unknown) => boolean;
    /** Matches arrays of exactly n elements */
    readonly length: (n: number) => (arr: readonly unknown[]) => boolean;
    /** Matches arrays with at least n elements */
    readonly minLength: (n: number) => (arr: readonly unknown[]) => boolean;
    /** Matches arrays whose first element satisfies a predicate */
    readonly head: <T>(pred: (value: T) => boolean) => (arr: readonly T[]) => boolean;
    /** Matches values in a set of allowed values */
    readonly oneOf: <T>(...values: T[]) => (value: T) => boolean;
    /** Matches values within a numeric range [lo, hi] inclusive */
    readonly between: (lo: number, hi: number) => (value: number) => boolean;
    /** Matches values satisfying all predicates */
    readonly allOf: <T>(...preds: Array<(value: T) => boolean>) => (value: T) => boolean;
    /** Matches values satisfying any predicate (OR combinator for guards) */
    readonly anyOf: <T>(...preds: Array<(value: T) => boolean>) => (value: T) => boolean;
    /** Matches objects that have a given property */
    readonly has: <K extends string>(key: K) => (value: unknown) => boolean;
    /** Matches strings against a regex */
    readonly regex: (pattern: RegExp) => (value: string) => boolean;
};
/**
 * Unified pattern matching — compile-time macro with runtime fallback.
 *
 * Three forms:
 * 1. `match(value, { variant: handler, ... })` — discriminated union / literal
 * 2. `match(value, { variant: handler, ... }, "discriminant")` — explicit discriminant
 * 3. `match(value, [when(...), otherwise(...)])` — guard predicates
 */
declare function match<T extends Record<string, unknown>, K extends keyof T, R>(value: T, handlers: DiscriminantHandlers<T, K, R>, discriminant?: K): R;
declare function match<T extends string | number, R>(value: T, handlers: LiteralHandlers<T, R>): R;
declare function match<T, R>(value: T, arms: GuardArm<T, R>[]): R;
/** @deprecated Use `match()` with literal keys instead */
declare function matchLiteral<T extends string | number, R>(value: T, handlers: LiteralHandlers<T, R>): R;
/** @deprecated Use `match()` with when()/otherwise() arms instead */
declare function matchGuard<T, R>(value: T, arms: Array<[(value: T) => boolean, (value: T) => R]>): R;
declare const matchMacro: _typesugar_core.ExpressionMacro;
declare const matchLiteralMacro: _typesugar_core.ExpressionMacro;
declare const matchGuardMacro: _typesugar_core.ExpressionMacro;

/**
 * Register Standard Library Instances Macro
 *
 * This macro registers all @typesugar/std typeclass instances in the compile-time
 * registry, enabling summon<>() resolution for standard types AND operator
 * dispatch via Op<> annotations.
 *
 * @example
 * ```typescript
 * // In your application entry point:
 * import { registerStdInstances } from "@typesugar/std/macros";
 *
 * registerStdInstances(); // Macro call - processed at compile time
 *
 * // Now you can use summon<>() for std instances:
 * import { summon } from "@typesugar/typeclass";
 * import type { Bounded, Numeric } from "@typesugar/std/typeclasses";
 *
 * const bounded = summon<Bounded<number>>();
 * console.log(bounded.minBound()); // Number.MIN_SAFE_INTEGER
 *
 * const numeric = summon<Numeric<number>>();
 * console.log(numeric.add(1, 2)); // 3
 *
 * // Operator dispatch works automatically:
 * // a === b → eqNumber.equals(a, b)
 * // a < b  → ordNumber.lessThan(a, b)
 * // a + b  → semigroupNumber.combine(a, b) or numericNumber.add(a, b)
 * ```
 *
 * ## Why is this needed?
 *
 * The @instance decorator cannot be used on const declarations in library
 * code because TypeScript's type declaration generator (tsc) doesn't accept
 * decorators on variable declarations. This macro provides an alternative
 * way to register instances at compile time.
 *
 * ## What gets registered?
 *
 * **Typeclasses (with Op<> syntax for operator dispatch):**
 * - Eq (Op<"===">, Op<"!==">) — equality comparison
 * - Ord (Op<"<">, Op<"<=">, Op<">">, Op<">=">) — ordering
 * - Semigroup (Op<"+">) — associative combine
 * - Monoid (extends Semigroup) — with identity
 * - Group (extends Monoid) — with inverse
 * - Numeric (Op<"+">, Op<"-">, Op<"*">) — ring arithmetic
 * - Integral (Op<"/">, Op<"%">) — integer division
 * - Fractional (Op<"/">) — real division
 *
 * **Instances:**
 * - Eq<number>, Eq<string>, Eq<boolean>, Eq<bigint>, Eq<Date>
 * - Ord<number>, Ord<string>, Ord<boolean>, Ord<bigint>, Ord<Date>
 * - Semigroup<number>, Semigroup<string>, Semigroup<bigint>
 * - Monoid<number>, Monoid<string>, Monoid<bigint>
 * - Group<number>, Group<bigint>
 * - Bounded<number>, Bounded<bigint>, Bounded<boolean>, Bounded<string>
 * - Enum<number>, Enum<boolean>, Enum<string>
 * - Numeric<number>, Numeric<bigint>
 * - Integral<number>, Integral<bigint>
 * - Fractional<number>
 * - Floating<number>
 * - FlatMap<Array>, FlatMap<Promise>, FlatMap<Iterable>, FlatMap<AsyncIterable>
 */

/**
 * Macro definition for registerStdInstances().
 *
 * When this macro is called, it:
 * 1. Ensures typeclass definitions are registered with their Op<> syntax
 * 2. Ensures all primitive instances are registered
 * 3. Returns a void expression (registration happens at module load)
 *
 * Note: Registration actually happens at module load time via performRegistration().
 * The macro call is a no-op but serves as documentation that the user expects
 * the standard instances to be available.
 */
declare const registerStdInstancesMacro: ExpressionMacro;
/**
 * Runtime stub for registerStdInstances.
 * This function does nothing at runtime - all work is done at compile time.
 */
declare function registerStdInstances(): void;

export { type GuardArm, P, isType, letYieldMacro, match, matchGuard, matchGuardMacro, matchLiteral, matchLiteralMacro, matchMacro, otherwise, parYieldMacro, registerLetYield, registerParYield, registerStdInstances, registerStdInstancesMacro, when };
