import type { Eq } from 'sts:compare';
import { type Option, type Result } from 'sts:result';
export type HashCode = number;
export interface Hash<T> {
    // #[effects(add: [], unknown: [direct])]
    hash(value: T): HashCode;
}
export interface HashEq<T> extends Hash<T>, Eq<T> {
}
type HashEqValue<THashEq> = THashEq extends HashEq<infer TValue> ? TValue : never;
// #[effects(add: [])]
export declare function fromHashEq<T>(hash: (value: T) => HashCode, equals: (left: T, right: T) => boolean): HashEq<T>;
// #[effects(add: [])]
export declare function contramap<A, B>(hashEq: HashEq<A>, project: (value: B) => A): HashEq<B>;
// #[effects(add: [])]
export declare function lazyHashEq<T>(getHashEq: () => HashEq<T>): HashEq<T>;
// #[effects(add: [])]
export declare function arrayHash<T>(itemHash: HashEq<T>): HashEq<readonly T[]>;
// #[effects(add: [])]
export declare function tupleHash<const THashEqs extends readonly HashEq<unknown>[]>(...elements: THashEqs): HashEq<{
    readonly [K in keyof THashEqs]: HashEqValue<THashEqs[K]>;
}>;
// #[effects(add: [])]
export declare function optionHash<T>(itemHash: HashEq<T>): HashEq<Option<T>>;
// #[effects(add: [])]
export declare function resultHash<T, E>(okHash: HashEq<T>, errHash: HashEq<E>): HashEq<Result<T, E>>;
export declare const stringHash: HashEq<string>;
export declare const numberHash: HashEq<number>;
export declare const booleanHash: HashEq<boolean>;
export declare const bigintHash: HashEq<bigint>;
// #[effects(add: [], unknown: [direct])]
export declare function combineHashes(...hashes: readonly HashCode[]): HashCode;
export {};
