dotResult 1.1.0
dotnet add package dotResult --version 1.1.0
NuGet\Install-Package dotResult -Version 1.1.0
<PackageReference Include="dotResult" Version="1.1.0" />
paket add dotResult --version 1.1.0
#r "nuget: dotResult, 1.1.0"
// Install dotResult as a Cake Addin #addin nuget:?package=dotResult&version=1.1.0 // Install dotResult as a Cake Tool #tool nuget:?package=dotResult&version=1.1.0
dotResult - The Result Monad for .NET
dotResult is a lightweight and intuitive implementation of the Result monad for the .NET platform. It simplifies error handling and value propagation in a functional way, improving code readability and safety.
Give it a star ⭐ !
If you find this project valuable, please consider giving it a star! Your support helps others discover this work and encourages further development.
Result<T>
API Documentation
Overview
The Result<T>
class represents the outcome of an operation that can either be a success or a failure. It provides various methods to handle the result, perform transformations, and handle both synchronous and asynchronous operations.
Properties
IsSuccess
public bool IsSuccess { get; }
Gets a value indicating whether the result represents a success.
Example:
var result = Success.From(42);
if (result.IsSuccess)
{
Console.WriteLine("Operation was successful!");
}
IsFailure
public bool IsFailure { get; }
Gets a value indicating whether the result represents a failure.
Example:
var result = Fail.OfType<int>(Failure.Fatal("Error", "An error occurred."));
if (result.IsFailure)
{
Console.WriteLine("Operation failed.");
}
Methods
Match
public TResult Match<TResult>(Func<Failure, TResult> failure, Func<T, TResult> success)
Matches the result and executes the appropriate function based on whether the result is a success or a failure.
Example:
var result = Success.From(42);
var message = result.Match(
failure => "Failed: " + failure.Message,
success => "Success: " + success);
Console.WriteLine(message);
MatchAsync
public async Task<TResult> MatchAsync<TResult>(Func<Failure, Task<TResult>> failure, Func<T, Task<TResult>> success)
Asynchronously matches the result and executes the appropriate asynchronous function based on whether the result is a success or a failure.
Example:
var result = Success.From(42);
var message = await result.MatchAsync(
async failure => await Task.FromResult("Failed: " + failure.Message),
async success => await Task.FromResult("Success: " + success));
Console.WriteLine(message);
MatchAsync
public async Task<TResult> MatchAsync<TResult>(Func<Failure, TResult> failure, Func<T, Task<TResult>> success)
Asynchronously matches the result and executes the appropriate function based on whether the result is a success or a failure.
Example:
var result = Success.From(42);
var message = await result.MatchAsync(
failure => "Failed: " + failure.Message,
async success => await Task.FromResult("Success: " + success));
Console.WriteLine(message);
Map
public Result<TResult> Map<TResult>(Func<T, TResult> map)
Transforms the value of a successful result using the provided mapping function.
Example:
var result = Success.From(42);
var mappedResult = result.Map(value => value.ToString());
Console.WriteLine(mappedResult.Match(
failure => "Failed",
success => "Success: " + success));
MapAsync
public async Task<Result<TResult>> MapAsync<TResult>(Func<T, Task<TResult>> map)
Asynchronously transforms the value of a successful result using the provided asynchronous mapping function.
Example:
var result = Success.From(42);
var mappedResult = await result.MapAsync(async value => await Task.FromResult(value.ToString()));
Console.WriteLine(mappedResult.Match(
failure => "Failed",
success => "Success: " + success));
Bind
public Result<TResult> Bind<TResult>(Func<T, Result<TResult>> map)
Transforms the value of a successful result using the provided mapping function that returns another Result
.
Example:
var result = Success.From(42);
var boundResult = result.Bind(value => Success.From(value.ToString()));
Console.WriteLine(boundResult.Match(
failure => "Failed",
success => "Success: " + success));
BindAsync
public async Task<Result<TResult>> BindAsync<TResult>(Func<T, Task<Result<TResult>>> map)
Asynchronously transforms the value of a successful result using the provided asynchronous mapping function that returns another Result
.
Example:
var result = Success.From(42);
var boundResult = await result.BindAsync(async value => await Task.FromResult(Success.From(value.ToString())));
Console.WriteLine(boundResult.Match(
failure => "Failed",
success => "Success: " + success));
Fold
public TState Fold<TState>(TState state, Func<TState, T, TState> folder)
Applies a folding function to the success value contained in the Result
, if present.
Example:
var result = Fail.OfType<int>(Failure.Fatal());
var foldedResult = result.Fold(0, (acc, value) => acc + value);
Console.WriteLine(foldedResult); // Outputs: 0
var result = Success.From(42);
var foldedResult = result.Fold(0, (acc, value) => acc + value);
Console.WriteLine(foldedResult); // Outputs: 42
var result = Success.From(42);
var foldedResult = result.Fold(10, (acc, value) => acc + value);
Console.WriteLine(foldedResult); // Outputs: 52
OrDefault
public T OrDefault(T defaultValue)
Returns the value of the result if it is a success; otherwise, returns the specified default value.
Example:
var result = Failure.OfType<int>(Failure.Fatal("Error", "An error occurred."));
var value = result.OrDefault(100);
Console.WriteLine(value); // Outputs: 100
var result = Some.From(42);
var value = result.OrDefault(100);
Console.WriteLine(value); // Outputs: 42
OrDefault
public T OrDefault(Func<T> defaultFactory)
Returns the value of the result if it is a success; otherwise, returns the value provided by the specified default value factory.
Example:
var result = Failure.OfType<int>(Failure.Fatal("Error", "An error occurred."));
var value = result.OrDefault(() => 100);
Console.WriteLine(value); // Outputs: 100
var result = Some.From(42);
var value = result.OrDefault(() => 100);
Console.WriteLine(value); // Outputs: 42
Static Methods
Implicit conversion from T
public static implicit operator Result<T>(T value)
Creates a new success result containing the provided value.
Example:
Result<int> result = 42;
Console.WriteLine(result.IsSuccess); // Outputs: True
Implicit conversion from Failure
public static implicit operator Result<T>(Failure failure)
Creates a new failure result containing the provided failure information.
Example:
var failure = Failure.Fatal("Error", "An error occurred.");
Result<int> result = failure;
Console.WriteLine(result.IsFailure); // Outputs: True
Static Methods on Static Class Result
Flatten
Flattens a nested Result<T>
by binding the inner result to the outer result.
public static Result<T> Flatten<T>(this Result<Result<T>> nested)
Example
var nestedSuccess = Result.Success(Result.Success(42));
var flattenedSuccess = nestedSuccess.Flatten(); // Result<int> with value 42
var nestedFailure = Result.Success(Result.Failure<int>(Failure.Fatal("Error", "Inner failure")));
var flattenedFailure = nestedFailure.Flatten(); // Result<int> with failure "Inner failure"
Map2
Combines two results and applies a mapping function if both results are successful.
public static Result<TResult> Map2<TValue, TOtherValue, TResult>(
Result<TValue> result1,
Result<TOtherValue> result2,
Func<TValue, TOtherValue, TResult> map)
Example
var result1 = Result.Success(2);
var result2 = Result.Success(3);
var combinedResult = Result.Map2(result1, result2, (x, y) => x + y); // Result<int> with value 5
var failureResult = Result.Failure<int>(Failure.Fatal("Error", "Calculation failed"));
var combinedFailure = Result.Map2(result1, failureResult, (x, y) => x + y); // Result<int> with failure "Calculation failed"
Map3
Combines three results and applies a mapping function if all three results are successful.
public static Result<TResult> Map3<T1, T2, T3, TResult>(
Result<T1> result1,
Result<T2> result2,
Result<T3> result3,
Func<T1, T2, T3, TResult> map)
Example
var result1 = Result.Success(1);
var result2 = Result.Success(2);
var result3 = Result.Success(3);
var combinedResult = Result.Map3(result1, result2, result3, (x, y, z) => x + y + z); // Result<int> with value 6
var failureResult = Result.Failure<int>(Failure.Fatal("Error", "Combination failed"));
var combinedFailure = Result.Map3(result1, result2, failureResult, (x, y, z) => x + y + z); // Result<int> with failure "Combination failed"
ToResult
Converts a value of type T
to a successful Result<T>
.
public static Result<T> ToResult<T>(this T value)
Example
var successResult = 42.ToResult(); // Result<int> with value 42
var stringResult = "Hello".ToResult(); // Result<string> with value "Hello"
ToResult
Converts a Failure
to a failed Result<T>
.
public static Result<T> ToResult<T>(this Failure failure)
Example
var failureResult = Failure.Fatal("Error", "Let the Galaxy burn").ToResult<int>(); // Result<int> with fatal failure "Let the Galaxy burn"
Query syntax
// Execute function if all results are in success state
Result<int> finalSuccessResult =
from v1 in Succes.From("Hello, World!")
from v2 in Succes.From('A')
from v3 in Succes.From(42)
let v4 = "Hello, World!"
select v1.Length + (int)v2 + v3 + v4.Length; // Result<int> with 133
// Returns failure from first result in failure state
Result<int> finalFailureResult =
from v1 in Failure.Fatal("Error", "Exception").ToResult<int>()
from v2 in Failure.Validation("Validation", "It is not a number").ToResult<decimal>()
from v3 in Failure.NotFound("NotFound", "Missing").ToResult<string>()
let v4 = "Hello, World!"
select v1 + (int)v2 + v3.Length + v4.Length; // Result<int> with fatal failure "Exception"
Contribution
If you would like to contribute to this project, check out CONTRIBUTING file.
License
This project is licensed under the terms of the MIT license.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
- add Fold method