export declare type USTM<A> = STM<never, never, A>;
export declare const STMSym: unique symbol;
export declare type STMSym = typeof STMSym;
export declare const _R: unique symbol;
export declare type _R = typeof _R;
export declare const _E: unique symbol;
export declare type _E = typeof _E;
export declare const _A: unique symbol;
export declare type _A = typeof _A;
/**
 * `STM<R, E, A>` represents an effect that can be performed transactionally,
 *  resulting in a failure `E` or a value `A` that may require an environment
 *  `R` to execute.
 *
 * Software Transactional Memory is a technique which allows composition of
 * arbitrary atomic operations.  It is the software analog of transactions in
 * database systems.
 *
 * The API is lifted directly from the Haskell package Control.Concurrent.STM
 * although the implementation does not resemble the Haskell one at all.
 *
 * See http://hackage.haskell.org/package/stm-2.5.0.0/docs/Control-Concurrent-STM.html
 *
 * STM in Haskell was introduced in:
 *
 * Composable memory transactions, by Tim Harris, Simon Marlow, Simon Peyton
 * Jones, and Maurice Herlihy, in ACM Conference on Principles and Practice of
 * Parallel Programming 2005.
 *
 * See https://www.microsoft.com/en-us/research/publication/composable-memory-transactions/
 *
 * See also:
 *  Lock Free Data Structures using STMs in Haskell, by Anthony Discolo, Tim
 *  Harris, Simon Marlow, Simon Peyton Jones, Satnam Singh) FLOPS 2006: Eighth
 *  International Symposium on Functional and Logic Programming, Fuji Susono,
 *  JAPAN, April 2006
 *
 *  https://www.microsoft.com/en-us/research/publication/lock-free-data-structures-using-stms-in-haskell/
 *
 * The implemtation is based on the ZIO STM module, while JS environments have
 * no race conditions from multiple threads STM provides greater benefits for
 * synchronization of Fibers and transactional data-types can be quite useful.
 *
 * @tsplus type ets/STM
 */
export interface STM<R, E, A> {
    readonly [STMSym]: STMSym;
    readonly [_R]: () => R;
    readonly [_E]: () => E;
    readonly [_A]: () => A;
}
/**
 * @tsplus type ets/STM/Ops
 */
export interface STMOps {
    $: STMAspects;
}
export declare const STM: STMOps;
/**
 * @tsplus type ets/STM/Aspects
 */
export interface STMAspects {
}
/**
 * @tsplus unify ets/STM
 */
export declare function unifySTM<X extends STM<any, any, any>>(self: X): STM<[
    X
] extends [{
    [_R]: () => infer R;
}] ? R : never, [
    X
] extends [{
    [_E]: () => infer E;
}] ? E : never, [
    X
] extends [{
    [_A]: () => infer A;
}] ? A : never>;
export declare class STMBase<R, E, A> implements STM<R, E, A> {
    readonly [STMSym]: STMSym;
    readonly [_R]: () => R;
    readonly [_E]: () => E;
    readonly [_A]: () => A;
}
//# sourceMappingURL=base.d.ts.map