// Map: transforms a TFailure result into a new failure result TFOut.
 public static Result2 <TSuccess, TFOut> ConvertFailure <TSuccess, TFOut, TFailure>(
     this Result2 <TSuccess, TFailure> input,
     Func <TFailure, TFOut> func)
 {
     return(input.IsFailure
         ? Result2 <TSuccess, TFOut> .Failed(func(input.FailureResult))
         : Result2 <TSuccess, TFOut> .Succeeded(input.SuccessResult));
 }
 // Map: maps a failure result into a success result (correct a failure)
 public static Result2 <TSuccess, TFailure> OnFailure <TSuccess, TFailure>(
     this Result2 <TSuccess, TFailure> input,
     Func <TFailure, TSuccess> func)
 {
     return(input.IsFailure
         ? Result2 <TSuccess, TFailure> .Succeeded(func(input.FailureResult))
         : input);
 }
 // Map; map a TSuccess result to a TOut result.
 public static Result2 <TOut, TFailure> OnSuccess <TSuccess, TFailure, TOut>(
     this Result2 <TSuccess, TFailure> input,
     Func <TSuccess, TOut> func)
 {
     return(input.IsSuccess
         ? Result2 <TOut, TFailure> .Succeeded(func(input.SuccessResult))
         : Result2 <TOut, TFailure> .Failed(input.FailureResult));
 }
        public static Result2 <TSuccess, TFailure> Ensure <TSuccess, TFailure>(
            this TSuccess result)
        {
            if (result != null)
            {
                return(Result2 <TSuccess, TFailure> .Succeeded(result));
            }

            return(Result2 <TSuccess, TFailure> .Failed(default(TFailure)));
        }
 // SelectMany must have the following signature:
 //   Result<C> SelectMany<A, B, C>(this Result<A> a, Func<A, Result<B>> func, Func<A, B, C> select)
 public static Result2 <TOut, TFailure> SelectMany <TReturnA, TReturnB, TOut, TFailure>(
     this Result2 <TReturnA, TFailure> self,
     Func <TReturnA, Result2 <TReturnB, TFailure> > func,
     Func <TReturnA, TReturnB, TOut> select)
 {
     if (self.IsSuccess)
     {
         var result = func(self.SuccessResult);
         if (result.IsSuccess)
         {
             return(Result2 <TOut, TFailure> .Succeeded(select(self.SuccessResult, result.SuccessResult)));
         }
         return(Result2 <TOut, TFailure> .Failed(result.FailureResult));
     }
     return(Result2 <TOut, TFailure> .Failed(self.FailureResult));
 }