import { type array, type listable } from "@ark/util";
import type { RootSchema } from "../kinds.ts";
import type { NodeCompiler } from "../shared/compile.ts";
import type { BaseNormalizedSchema, declareNode } from "../shared/declare.ts";
import { type nodeImplementationOf, type RootKind } from "../shared/implement.ts";
import type { JsonSchema } from "../shared/jsonSchema.ts";
import type { ToJsonSchema } from "../shared/toJsonSchema.ts";
import type { Traversal, TraverseAllows, TraverseApply } from "../shared/traversal.ts";
import { BaseRoot } from "./root.ts";
export declare namespace Morph {
    interface Inner {
        readonly in?: BaseRoot;
        readonly morphs: array<Morph | BaseRoot>;
        readonly declaredIn?: BaseRoot;
        readonly declaredOut?: BaseRoot;
    }
    interface Schema extends BaseNormalizedSchema {
        readonly in?: RootSchema;
        readonly morphs: listable<Morph | BaseRoot>;
        readonly declaredIn?: BaseRoot;
        readonly declaredOut?: BaseRoot;
    }
    interface Declaration extends declareNode<{
        kind: "morph";
        schema: Schema;
        normalizedSchema: Schema;
        inner: Inner;
        childKind: RootKind;
    }> {
    }
    type Node = MorphNode;
    type In<morph extends Morph> = morph extends Morph<infer i> ? i : never;
    type Out<morph extends Morph> = morph extends Morph<never, infer o> ? o : never;
    type ContextFree<i = never, o = unknown> = (In: i) => o;
}
export type Morph<i = never, o = unknown> = (In: i, ctx: Traversal) => o;
export declare class MorphNode extends BaseRoot<Morph.Declaration> {
    serializedMorphs: string[];
    compiledMorphs: string;
    lastMorph: Morph | BaseRoot | undefined;
    lastMorphIfNode: BaseRoot | undefined;
    introspectableIn: BaseRoot | undefined;
    introspectableOut: BaseRoot | undefined;
    get shallowMorphs(): array<Morph>;
    get rawIn(): BaseRoot;
    get rawOut(): BaseRoot;
    declareIn(declaredIn: BaseRoot): MorphNode;
    declareOut(declaredOut: BaseRoot): MorphNode;
    expression: string;
    get defaultShortDescription(): string;
    protected innerToJsonSchema(ctx: ToJsonSchema.Context): JsonSchema;
    compile(js: NodeCompiler): void;
    traverseAllows: TraverseAllows;
    traverseApply: TraverseApply;
    /** Check if the morphs of r are equal to those of this node */
    hasEqualMorphs(r: MorphNode): boolean;
}
export declare const Morph: {
    implementation: nodeImplementationOf<Morph.Declaration>;
    Node: typeof MorphNode;
};
export declare const writeMorphIntersectionMessage: (lDescription: string, rDescription: string) => string;
