import { PType } from "../../../PType/index.js";
import { TermFn, PData, PLam, PInt, PList, PPair, PByteString, PBool, PAsData } from "../../../PTypes/index.js";
import { Term } from "../../../Term/index.js";
import { TermType, ToPType } from "../../../type_system/index.js";
import { UtilityTermOf } from "../../std/UtilityTerms/addUtilityForType.js";
import { PappArg } from "../../pappArg.js";
import { TermBS } from "../../std/UtilityTerms/TermBS.js";
/**
 * in theory 'chooseData' has 5 type parameters (1 per data constructor)
 * and this means any of those types can be returned
 *
 * plu-ts wont support that in favor of type determinism
 */
export declare function pstrictChooseData<ReturnT extends TermType>(returnT: ReturnT): TermFn<[PData, ToPType<ReturnT>, ToPType<ReturnT>, ToPType<ReturnT>, ToPType<ReturnT>, ToPType<ReturnT>], ToPType<ReturnT>>;
type CaseBFn<RetT extends PType> = (bCase: PappArg<RetT>) => UtilityTermOf<RetT>;
export type CaseIFn<RetT extends PType> = (iCase: PappArg<RetT>) => Term<PLam<RetT, RetT>> & {
    caseB: CaseBFn<RetT>;
    $: CaseBFn<RetT>;
};
export type CaseListFn<RetT extends PType> = (listCase: PappArg<RetT>) => Term<PLam<RetT, PLam<RetT, RetT>>> & {
    caseI: CaseIFn<RetT>;
    $: CaseIFn<RetT>;
};
export type CaseMapFn<RetT extends PType> = (mapCase: PappArg<RetT>) => Term<PLam<RetT, PLam<RetT, PLam<RetT, RetT>>>> & {
    caseList: CaseListFn<RetT>;
    $: CaseListFn<RetT>;
};
export type CaseConstrFn<RetT extends PType> = (constrCase: PappArg<RetT>) => Term<PLam<RetT, PLam<RetT, PLam<RetT, PLam<RetT, RetT>>>>> & {
    caseMap: CaseMapFn<RetT>;
    $: CaseMapFn<RetT>;
};
export declare function pchooseData<ReturnT extends TermType>(returnT: ReturnT): Term<PLam<PData, PLam<ToPType<ReturnT>, PLam<ToPType<ReturnT>, PLam<ToPType<ReturnT>, PLam<ToPType<ReturnT>, PLam<ToPType<ReturnT>, ToPType<ReturnT>>>>>>>> & {
    $: (pdata: PappArg<PData>) => Term<PLam<ToPType<ReturnT>, PLam<ToPType<ReturnT>, PLam<ToPType<ReturnT>, PLam<ToPType<ReturnT>, PLam<ToPType<ReturnT>, ToPType<ReturnT>>>>>>> & {
        caseConstr: CaseConstrFn<ToPType<ReturnT>>;
        $: CaseConstrFn<ToPType<ReturnT>>;
    };
};
export declare const pConstrToData: TermFn<[PInt, PList<PData>], PData>;
type PMap<K extends PType, V extends PType> = PList<PPair<K, V>>;
export declare const pMapToData: TermFn<[PMap<PData, PData>], PData>;
export declare const pListToData: TermFn<[PList<PData>], PData>;
export declare const pIntToData: TermFn<[PInt], PAsData<PInt>>;
export declare const pBSToData: TermFn<[PByteString], PAsData<PByteString>>;
export declare const punConstrData: TermFn<[PData], PPair<PInt, PList<PData>>>;
export declare const punMapData: TermFn<[PData, PData], PList<PPair<PData, PData>>>;
export declare const punListData: TermFn<[PData], PList<PData>>;
export declare const punIData: TermFn<[PData], PInt>;
export declare const punBData: Term<PLam<PData, PByteString>> & {
    $: (dataBS: PappArg<PData>) => TermBS;
};
export declare const peqData: TermFn<[PData, PData], PBool>;
export declare const pnilData: Term<PList<PData>>;
export declare const pnilPairData: Term<PList<PPair<PData, PData>>>;
export declare const pserialiseData: TermFn<[PData], PByteString>;
export {};
