dotResult 1.1.0

dotnet add package dotResult --version 1.1.0                
NuGet\Install-Package dotResult -Version 1.1.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="dotResult" Version="1.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add dotResult --version 1.1.0                
#r "nuget: dotResult, 1.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// 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

.net workflow

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .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.

Version Downloads Last updated
1.1.0 109 7/25/2024
1.0.0 70 7/11/2024
0.5.0 85 7/9/2024
0.4.0 87 7/8/2024
0.3.0 86 7/7/2024
0.2.0 83 7/6/2024
0.1.0 87 7/6/2024
0.0.1 89 7/5/2024

- add Fold method