import { Monad, MonadHKT } from './Monad';
import { Optional } from './Optional';
export interface ResultHKT<ErrorT> extends MonadHKT {
    output: Result<this["input"], ErrorT>;
}
export declare class Result<ValueT, ErrorT> extends Monad<ValueT> {
    _success: boolean;
    _value: ValueT | ErrorT;
    constructor(_success: boolean, _value: ValueT | ErrorT);
    /**
     * Used to wrap a potential error throwing function into a safe Result wrapped function. Usage looks like:
     * ```ts
     * const safeJsonParse = Result.wrap<typeof JSON.parse, SyntaxError>(JSON.parse)
     * ```
     * @param fn
     */
    static wrap<FnT extends (...args: any[]) => any, ErrorT>(fn: FnT): (...args: Parameters<FnT>) => Result<ReturnType<FnT>, ErrorT>;
    /**
     * If Ok, this uses the mapping function to transform Value to a new Value, and returns Result<New Value, ErrorT>
     *   otherwise it propagates the ErrorT.
     * @param mapping
     */
    map<B>(mapping: (value: ValueT) => B): Result<B, ErrorT>;
    amap<B>(mapping: Result<(value: ValueT) => B, ErrorT>): Result<B, ErrorT>;
    pure<B>(value: B): Result<B, ValueT>;
    /**
     * If Ok, the mapping of ValueT to a Result is run, otherwise the Error is propagated. If you want to just transform
     * ValueT to a new Value, use `.map`
     * @param mapping
     */
    then<B>(mapping: (value: ValueT) => Result<B, ErrorT>): Result<B, ErrorT>;
    /**
     * Returns the ValueT if Ok, otherwise it returns `defaultValue`
     * @param defaultValue
     */
    or<B>(defaultValue: B): ValueT | B;
    /**
     * If Err this runs the mapping from ErrorT => ValueT, otherwise it returns a new Result containing ValueT
     * @param mapping
     */
    catch<NewErrorT>(mapping: (value: ErrorT) => ValueT): Result<ValueT, NewErrorT>;
    /**
     * If Err this runs the mapping from ErrorT => Result<ValueT, NewErrorT>, otherwise it returns a new Result containing
     * ValueT
     * @param mapping
     */
    catchThen<NewErrorT>(mapping: (value: ErrorT) => Result<ValueT, NewErrorT>): Result<ValueT, NewErrorT>;
    /**
     * Returns the ValueT if Ok, otherwise it throws ErrorT. This is the nuclear option, `.or(default)` should be preferred.
     */
    unwrap(): ValueT;
    /**
     * Converts a Result<ValueT, ErrorT> to an Optional<ValueT>
     */
    toOptional(): Optional<ValueT>;
}
/**
 * Used to construct an Ok value, for example:
 *
 * @example
 * ```ts
 * type ErrorMessage = string
 *
 * function safeDivide(a: number, b: number): Result<number, ErrorMessage> {
 *   if (b === 0) {
 *     return Err("Can't divide by zero")
 *   } else {
 *     return Ok(a / b)
 *   }
 * }
 * ```
 * @param value
 */
export declare function Ok<ValueT, ErrorT>(value: ValueT): Result<ValueT, ErrorT>;
/**
 * Used to construct an Err value, for example:
 *
 * @example
 * ```ts
 * type ErrorMessage = string
 *
 * function safeDivide(a: number, b: number): Result<number, ErrorMessage> {
 *   if (b === 0) {
 *     return Err("Can't divide by zero")
 *   } else {
 *     return Ok(a / b)
 *   }
 * }
 * ```
 * @param value
 */
export declare function Err<ValueT, ErrorT>(value: ErrorT): Result<ValueT, ErrorT>;
