Async Programming with Monads
Both Result<T> and Maybe<T> provide full async support for all major operations.
Async Map
var result = await Result.Success("file.txt") .Map(async fileName => await File.ReadAllTextAsync(fileName));var maybe = await Maybe.Some("data") .Map(async data => await ProcessDataAsync(data));Async Bind
public async Task<Result<User>> GetUserAsync(int id) => await ValidateId(id) .Bind(async validId => await database.GetUserAsync(validId));var result = await Maybe.Some(userId) .Bind(async id => await FindUserAsync(id));Async Side Effects
var result = await CreateUserAsync(email) .IfSuccess(async user => await SendWelcomeEmailAsync(user)) .IfFailure(async error => await LogErrorAsync(error));await maybe .IfSome(async value => await ProcessValueAsync(value)) .IfNone(async () => await HandleMissingValueAsync());Async Match
var message = await result.Match( async user => await FormatUserDetailsAsync(user), async error => await FormatErrorMessageAsync(error));Async Ensure
var validated = await result .Ensure(async user => await IsUserActiveAsync(user), new LogicError("User is not active"));Task Extensions
All methods work seamlessly with Task<Result<T>> and Task<Maybe<T>>:
public async Task<Result<ProcessedData>> ProcessUserDataAsync(int userId){ return await GetUserAsync(userId) // Task<Result<User>> .Bind(async user => await GetUserDataAsync(user.Id)) .Map(async data => await ProcessDataAsync(data)) .IfSuccess(async result => await CacheResultAsync(result));}Safe Async Execution
// Catches exceptions as RuntimeErrorvar result = await Result.Execute(async () => await RiskyAsyncOperation());See Also
Result\ Monad Core Result monad operations and patterns
Maybe\ Monad Core Maybe monad operations and patterns