Bogoware.Monads porta due degli strumenti più semplici della programmazione funzionale nel C# idiomatico: un Maybe<T> per un valore che può mancare, e un Result<T> per un’operazione che può fallire. Lo scopo non è far somigliare C# a Haskell. È spostare due intere famiglie di bug dal runtime al sistema dei tipi. Un valore che potrebbe non esserci è un Maybe<T>, e il caso vuoto non si può dimenticare. Un’operazione che potrebbe fallire restituisce un Result<T>, e il fallimento è un valore con cui devi fare i conti, non un’eccezione che srotola lo stack da un punto che non stavi guardando.
È la stessa inclinazione che sta dietro agli articoli: rendere espliciti i casi scomodi e farli controllare al compilatore. I null e le eccezioni vaganti sono complicazione accidentale, quella che il buon design tiene fuori dai piedi; un Maybe o un Result nella firma è il modello che dice la verità su quello che può succedere.
using Bogoware.Monads;
// Absence lives in the type — no nulls, no NullReferenceExceptions.
public string DisplayName(Maybe<string> nickname, string fallback) =>
nickname.Map(n => $"@{n}").GetValue(fallback);
// Failure is a value you must handle — no hidden exceptions.
public Result<User> Register(string email, string password) =>
ValidateEmail(email)
.Bind(() => ValidatePassword(password))
.Map(() => new User(email, password));
string message = Register(email, password).Match(
user => $"Welcome, {user.Email}",
error => $"Could not register: {error.Message}"); Si compone come ci si aspetta: Map, Bind, Match, sintassi di query LINQ, overload asincroni e helper per collezioni IEnumerable<Maybe<T>> e IEnumerable<Result<T>>. Gli errori sono una piccola gerarchia estensibile, non stringhe, così un fallimento significa ancora qualcosa quando arriva al chiamante. Supporta .NET Standard 2.1 e .NET 8/9/10.
- Pacchetto — nuget.org/packages/Bogoware.Monads
- Sorgente — github.com/bogoware/monads
- Documentazione — bogoware.github.io/Monads