/** * Type representation for Dvala's set-theoretic type system. * * Every type denotes a set of values. Type operations are set operations: * - Union (A | B) = set union * - Intersection (A & B) = set intersection * - Negation (!A) = set complement * - Subtyping (A <: B) = set containment * * Design: side-table only, erased after checking. Zero runtime cost. */ export type PrimitiveName = 'Number' | 'String' | 'Boolean' | 'Null'; /** * Effect set: a set of effect names, optionally open (polymorphic). * open=true: "these effects plus possibly more" (@{log, e...}) * open=false: "exactly these effects" (@{log, fetch}) * Empty closed set = pure function. */ export interface EffectSet { effects: Set; open: boolean; } export interface HandlerEffectSignature { argType: Type; retType: Type; } export interface HandlerWrapperInfo { paramIndex: number; handled: Map; /** * Effects the wrapper itself introduces — performed by the inner handler's * clauses or transform clause when the handler runs over the thunk arg. * At call sites, the resulting effect set is `(thunk_effects \ handled) ∪ introduced`, * mirroring the do-with-h application law (see HandlerType.introduced). */ introduced: EffectSet; } export interface FunctionType { tag: 'Function'; params: Type[]; restParam?: Type; ret: Type; effects: EffectSet; handlerWrapper?: HandlerWrapperInfo; } export interface SequenceType { tag: 'Sequence'; prefix: Type[]; rest: Type; minLength: number; maxLength?: number; } /** The empty (pure) effect set. Frozen to prevent accidental mutation. */ export declare const PureEffects: EffectSet; export type Type = { tag: 'Primitive'; name: PrimitiveName; } | { tag: 'Atom'; name: string; } | { tag: 'Literal'; value: string | number | boolean; } | FunctionType | { tag: 'Handler'; body: Type; output: Type; handled: Map; introduced: EffectSet; } | { tag: 'AnyFunction'; } | { tag: 'Tuple'; elements: Type[]; } | { tag: 'Record'; fields: Map; open: boolean; } | { tag: 'Array'; element: Type; } | SequenceType | { tag: 'Regex'; } | { tag: 'Union'; members: Type[]; } | { tag: 'Inter'; members: Type[]; } | { tag: 'Neg'; inner: Type; } | { tag: 'Unknown'; } | { tag: 'Never'; } | { tag: 'Var'; id: number; level: number; lowerBounds: Type[]; upperBounds: Type[]; displayLowerBounds?: Type[]; displayUpperBounds?: Type[]; } | { tag: 'Alias'; name: string; args: Type[]; expanded: Type; } | { tag: 'Recursive'; id: number; body: Type; }; export declare const NumberType: Type; export declare const StringType: Type; export declare const BooleanType: Type; export declare const NullType: Type; export declare const Unknown: Type; export declare const Never: Type; export declare const RegexType: Type; export declare const AnyFunction: Type; export declare function atom(name: string): Type; export declare function literal(value: string | number | boolean): Type; export declare function fn(params: Type[], ret: Type, effects?: EffectSet, handlerWrapper?: HandlerWrapperInfo, restParam?: Type): Type; export declare function functionAcceptsArity(t: FunctionType, arity: number): boolean; export declare function getFunctionParamType(t: FunctionType, index: number): Type | undefined; export declare function functionArityLabel(t: FunctionType): string; export declare function handlerType(body: Type, output: Type, handled: Map, introduced?: EffectSet): Type; export declare function tuple(elements: Type[]): Type; export declare function record(fields: Record, open?: boolean): Type; export declare function array(element: Type): Type; export declare function sequence(prefix: Type[], rest: Type, minLength?: number, maxLength?: number): SequenceType; export declare function toSequenceType(type: Type): SequenceType | undefined; export declare function normalizeSequenceType(type: SequenceType): SequenceType; export declare function sequenceElementAt(type: SequenceType, index: number): Type; export declare function sequenceMayHaveIndex(type: SequenceType, index: number): boolean; export declare function union(...members: Type[]): Type; export declare function inter(...members: Type[]): Type; export declare function neg(inner: Type): Type; export declare function typeToString(t: Type): string; /** Display an effect set. Returns empty string for pure (empty closed) sets. */ export declare function effectSetToString(e: EffectSet): string; export declare function typeEquals(a: Type, b: Type): boolean; /** Check if two effect sets are equal. */ export declare function effectSetEquals(a: EffectSet, b: EffectSet): boolean; /** Create an effect set from named effects. */ export declare function effectSet(effects: string[], open?: boolean): EffectSet; /** Merge two effect sets (union of effects). */ export declare function mergeEffects(a: EffectSet, b: EffectSet): EffectSet; /** Subtract handled effects from an effect set. */ export declare function subtractEffects(from: EffectSet, handled: Set): EffectSet; /** Check if an effect set is a subset of another (fewer effects = subtype). */ export declare function isEffectSubset(sub: EffectSet, sup: EffectSet): boolean;