Result<T> Monad
The Result<T> monad is designed for modeling operations that can either fail or return a value. It is a generic type, with T representing the type of the value returned by the successful operation.
Design Goals
Result<T> provides a set of methods that facilitate chaining operations in a functional way:
| Method | Purpose |
|---|---|
Map | Transform the value (happy flow) |
MapError | Transform the error (unhappy flow) |
Bind | Chain operations returning Result<T> |
Match | Handle both success and failure paths |
RecoverWith | Recover from an error |
Ensure | Assert a condition on the value |
IfSuccess | Execute side effects on success |
IfFailure | Execute side effects on failure |
Creating Results
// Successvar success = Result.Success(42);var unitSuccess = Result.Unit; // For void operations
// Failurevar failure = Result.Failure<int>("Something went wrong");var customFailure = Result.Failure<int>(new CustomError("Details"));
// From valuesvar fromValue = Result.From(42);Core Operations
Map
Transforms the value if the result is successful:
var result = Result.Success(42);var doubled = result.Map(x => x * 2); // Result<int> with 84var text = result.Map(x => $"Value: {x}"); // Result<string>Bind
Chains operations that return Result<T>:
public Result<int> ParseNumber(string text) => int.TryParse(text, out var num) ? Result.Success(num) : Result.Failure<int>("Invalid number");
var result = ParseNumber("42") .Bind(n => ValidateRange(n)) .Map(n => n * 2);Match
Handles both success and failure cases:
var message = result.Match( value => $"Success: {value}", error => $"Failed: {error.Message}");Unsafe Methods
// Extract value (throws if failure)var value = result.Value;var value2 = result.GetValueOrThrow();
// Extract error (throws if success)var error = failedResult.Error;
// Throw if failureresult.ThrowIfFailure();See Also
Error Types Learn about the structured error hierarchy
Maybe\ Monad Handle optional values with Maybe
Async Programming Use Result with async/await patterns