/**
 * Created by tushar on 07/09/19
 */
import { NoSuchValueException } from '../internals/noSuchValueException';
import { Option } from './option';
/**
 * A data structure that represents Success/Failure & optional types
 * @typeparam L1 Represents Left case that can be used to depict failures.
 * @typeparam R1 Represents Right case that can be used to depict success.
 */
export declare abstract class Either<L1, R1> {
    /**
     * Converts an [[Either]] to an [[Option]]
     */
    readonly asOption: Option<R1>;
    /**
     * Creates an [[Either]] from [[Option]]
     */
    static fromOption<R>(option: Option<R>): Either<NoSuchValueException, R>;
    /**
     * Returns true if the either is of [[Left]] type.
     */
    static isLeft<L1, R1>(either: Either<L1, R1>): either is Left<L1>;
    /**
     * Returns true if the either is of [[Right]] type.
     */
    static isRight<L1, R1>(either: Either<L1, R1>): either is Right<R1>;
    /**
     * Creates an object of [[Left]] type.
     */
    static left<L>(left: L): Either<L, never>;
    /**
     * Creates an object of [[Right]] type.
     */
    static right<R>(right: R): Either<never, R>;
    /**
     * Creates a new [[Either]] type from a function that could fail with an error.
     */
    static try<E1 = Error, A1 = unknown>(cb: () => A1): Either<E1, A1>;
    /**
     * Like [[Either.map]] it uses the left function to chain over object of [[Left]] type
     * and the right function to chain over an object of [[Right]] type.
     */
    abstract biChain<L2, R2>(LL: (l: L1) => Either<L2, R2>, RR: (r: R1) => Either<L2, R2>): Either<L2, R2>;
    /**
     * It uses the left function to chain over object of [[Left]] type
     * and the right function to chain over an object of [[Right]] type.
     */
    biMap<L2, R2>(LL: (l: L1) => L2, RR: (r: R1) => R2): Either<L2, R2>;
    /**
     * Alias for [[Either.chainR]]
     */
    chain<R2>(ab: (r: R1) => Either<L1, R2>): Either<L1, R2>;
    /**
     * Sequentially converts a [[Left]] type to another [[Left]] type.
     */
    chainL<L2>(ab: (l: L1) => Either<L2, R1>): Either<L2, R1>;
    /**
     * Sequentially converts a [[Right]] type to another [[Right]] type.
     */
    chainR<R2>(ab: (r: R1) => Either<L1, R2>): Either<L1, R2>;
    /**
     * Reduces an [[Either]] to a value of type S by providing a seed value
     */
    abstract fold<S>(seed: S, LL: (l: L1, s: S) => S, RR: (r: R1, s: S) => S): S;
    /**
     * Gets the left value if available or else returns the provided default value
     */
    abstract getLeftOrElse(left: L1): L1;
    /**
     * Gets the right value if available or else returns the provided default value
     */
    abstract getRightOrElse(right: R1): R1;
    /**
     * Alias for [[Either.mapR]]
     */
    map<R2>(ab: (r: R1) => R2): Either<L1, R2>;
    /**
     * Transforms the left value
     */
    mapL<L2>(ab: (r: L1) => L2): Either<L2, R1>;
    /**
     * Transforms the right value
     */
    mapR<R2>(ab: (r: R1) => R2): Either<L1, R2>;
    /**
     * Reduces an [[Either]] to a value of type S by providing a seed value
     */
    abstract reduce<S>(LL: (l: L1) => S, RR: (r: R1) => S): S;
}
/**
 * Data structure that represents a left value
 */
export declare class Left<L1> extends Either<L1, never> {
    readonly value: L1;
    constructor(value: L1);
    /**
     * Refer [[Either.biChain]]
     */
    biChain<L2, R2>(LL: (l: L1) => Either<L2, R2>, RR: (r: never) => Either<L2, R2>): Either<L2, R2>;
    /**
     * Refer [[Either.fold]]
     */
    fold<S>(S: S, LL: (l: L1, s: S) => S, RR: (r: never, s: S) => S): S;
    /**
     * Refer [[Either.getLeftOrElse]]
     */
    getLeftOrElse(left: L1): L1;
    /**
     * Refer [[Either.getRightOrElse]]
     */
    getRightOrElse(right: never): never;
    /**
     * Refer [[Either.reduce]]
     */
    reduce<S>(LL: (l: L1) => S, RR: (r: never) => S): S;
}
/**
 * Data structure that represents a right value
 */
export declare class Right<R1> extends Either<never, R1> {
    readonly value: R1;
    constructor(value: R1);
    /**
     * Refer [[Either.biChain]]
     */
    biChain<L2, R2>(LL: (l: never) => Either<L2, R2>, RR: (r: R1) => Either<L2, R2>): Either<L2, R2>;
    /**
     * Refer [[Either.fold]]
     */
    fold<S>(S: S, LL: (l: never, s: S) => S, RR: (r: R1, s: S) => S): S;
    /**
     * Refer [[Either.getLeftOrElse]]
     */
    getLeftOrElse(left: never): never;
    /**
     * Refer [[Either.getRightOrElse]]
     */
    getRightOrElse(right: R1): R1;
    /**
     * Refer [[Either.reduce]]
     */
    reduce<S>(LL: (l: never) => S, RR: (r: R1) => S): S;
}
