/**
 * @typed/fp/Fx is a generator-based do-notation for single-shot data types.
 *
 * @since 0.13.0
 */
import { Applicative2 } from 'fp-ts/Applicative';
import { Apply2 } from 'fp-ts/Apply';
import { ChainRec2 } from 'fp-ts/ChainRec';
import { Either } from 'fp-ts/Either';
import { FromIO2 } from 'fp-ts/FromIO';
import { Functor2 } from 'fp-ts/Functor';
import { IO } from 'fp-ts/IO';
import { Monad2 } from 'fp-ts/Monad';
import { Pointed2 } from 'fp-ts/Pointed';
import { A } from 'ts-toolbelt';
/**
 * Fx is a generator-based abstraction for do-notation for any single-shot
 * effect. Due to the mutable nature of generators however, we cannot support this syntax
 * for multi-shot effects like reactive Streams/Observables. Most of the effects you
 * likely use are single-shot like Option/Either/Task.
 *
 * An Fx is a set of Effects which are being `yield`ed from the Generator.
 * This can be a powerful way to construct algorithms separate from their interpretation.
 *
 * Fx's Result parameter is the secret to getting type-safety by using yield* when running an Fx.
 *
 * @category Model
 * @since 0.13.0
 */
export interface Fx<Effects, Result, Next = unknown> {
    readonly [Symbol.iterator]: () => Generator<Effects, Result, Next>;
}
/**
 * Extract the effects being performed within an Fx
 * @category Type-level
 * @since 0.13.0
 */
export declare type GetEffects<A> = A extends Fx<infer R, any, any> ? IsNever<R> extends false ? R : unknown : unknown;
declare type IsNever<A> = A.Equals<[never], [A]> extends 1 ? true : false;
/**
 * Extract the result being performed within an Fx
 * @category Type-level
 * @since 0.13.0
 */
export declare type GetResult<A> = A extends Fx<any, infer R, any> ? R : never;
/**
 * Extract the values being returned to the internal Fx
 * @category Type-level
 * @since 0.13.0
 */
export declare type GetNext<A> = A extends Fx<any, any, infer R> ? R : never;
/**
 * Extract the values being returned to the internal Fx
 * @category Combinator
 * @since 0.13.0
 */
export declare function doFx<G extends Generator<any, any, any>>(generatorFn: () => G): Fx<GetEffects<G>, GetResult<G>, GetNext<G>>;
/**
 * An Fx which has no Effects or they have all been accounted for.
 * @category Model
 * @since 0.13.0
 */
export interface Pure<A> extends Fx<never, A> {
}
/**
 * @category Constructor
 * @since 0.13.0
 */
export declare const pure: <A>(value: A) => Pure<A>;
/**
 * @category Constructor
 * @since 0.13.0
 */
export declare const fromIO: <A>(io: IO<A>) => Pure<A>;
/**
 * @category URI
 * @since 0.13.0
 */
export declare const URI = "@typed/fp/Fx";
/**
 * @category URI
 * @since 0.13.0
 */
export declare type URI = typeof URI;
declare module 'fp-ts/HKT' {
    interface URItoKind2<E, A> {
        [URI]: Fx<E, A>;
    }
}
/**
 * @category Combinator
 * @since 0.13.0
 */
export declare const map: <A, B>(f: (value: A) => B) => <E>(fa: Fx<E, A, unknown>) => Fx<E, B, unknown>;
/**
 * @category Instance
 * @since 0.13.0
 */
export declare const Functor: Functor2<URI>;
/**
 * @category Constructor
 * @since 0.13.0
 */
export declare const of: <A>(value: A) => Pure<A>;
/**
 * @category Instance
 * @since 0.13.0
 */
export declare const Pointed: Pointed2<URI>;
/**
 * @category Combinator
 * @since 0.13.0
 */
export declare const chain: <A, E1, B>(f: (value: A) => Fx<E1, B, unknown>) => <E2>(fa: Fx<E2, A, unknown>) => Fx<E1 | E2, B, unknown>;
/**
 * @category Instance
 * @since 0.13.0
 */
export declare const Monad: Monad2<URI>;
/**
 * @category Combinator
 * @since 0.13.0
 */
export declare const chainRec: <A, E, B>(f: (value: A) => Fx<E, Either<A, B>, unknown>) => (value: A) => Fx<E, B, unknown>;
/**
 * @category Instance
 * @since 0.13.0
 */
export declare const ChainRec: ChainRec2<URI>;
/**
 * @category Combinator
 * @since 0.13.0
 */
export declare const ap: <E1, A>(fa: Fx<E1, A, unknown>) => <E2, B>(fab: Fx<E2, (a: A) => B, unknown>) => Fx<E1 | E2, B, unknown>;
/**
 * @category Instance
 * @since 0.13.0
 */
export declare const Apply: Apply2<URI>;
/**
 * @category Instance
 * @since 0.13.0
 */
export declare const Applicative: Applicative2<URI>;
/**
 * @category Instance
 * @since 0.13.0
 */
export declare const FromIO: FromIO2<URI>;
export {};
//# sourceMappingURL=Fx.d.ts.map