/// <summary>
        /// Performs a mapping depending on the type of the stored value.
        /// </summary>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <typeparam name="TResult">The resultant type.</typeparam>
        /// <param name="result">The result.</param>
        /// <param name="onSuccess">The mapping for a value.</param>
        /// <param name="onError">The mapping for an error.</param>
        /// <returns>The mapped result.</returns>
        public static TResult Match <TValue, TResult>(this IResult result, Func <TValue?, TResult> onSuccess, Func <Error, TResult> onError)
        {
            if (result.IsSuccess && onSuccess != null)
            {
                return(onSuccess(result.AsSuccess <TValue>().Value));
            }

            if (result.IsSuccess == false && onError != null)
            {
                return(onError(result.AsFail().Error));
            }

            throw new InvalidOperationException();
        }
        /// <summary>
        /// Executes one of the actions depending on the type of the stored value.
        /// </summary>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="result">The result.</param>
        /// <param name="onSuccess">The action to execute for a value.</param>
        /// <param name="onError">The action to execute for an error.</param>
        public static void Switch <TValue>(this IResult result, Action <TValue?> onSuccess, Action <Error> onError)
        {
            if (result.IsSuccess && onSuccess != null)
            {
                onSuccess(result.AsSuccess <TValue>().Value);
                return;
            }

            if (result.IsSuccess == false && onError != null)
            {
                onError(result.AsFail().Error);
                return;
            }

            throw new InvalidOperationException();
        }