For the complete documentation index, see llms.txt. This page is also available as Markdown.

Quickstart

Install the package and get both types working, without leaving this page.

Ready to stop writing null checks and stop catching exceptions you expected? Here is the whole setup.

Install

dotnet add package Waystone.Monads

That is the only package you need. The analyzer and the source generator come with it, already switched on.

Add the usings

using Waystone.Monads; on its own gets you nothing. The root namespace holds no types, so that line compiles and then every type name fails with CS0234. Pick the namespaces you need instead:

Namespace
What it holds

Waystone.Monads.Options

Option<T> and the static Option factories

Waystone.Monads.Options.Extensions

Extension methods on Option<T>: Flatten, Transpose, Unzip, UnwrapOrNull, the collection helpers, and every Async overload

Waystone.Monads.Results

Result<TOk, TErr> and the static Result factories

Waystone.Monads.Results.Extensions

Extension methods on Result<TOk, TErr>: Flatten, Transpose, UnwrapOrNull, the collection helpers, and every Async overload

Waystone.Monads.Results.Errors

Error, ErrorCode and [ErrorCodeCatalog]

Waystone.Monads.Exceptions

UnwrapException and UnmetExpectationException

Waystone.Monads.Configs

MonadOptions and ErrorCodeFactory

On C# 10 or later, put the ones you use everywhere in a single GlobalUsings.cs and stop repeating them per file:

global using Waystone.Monads.Options;
global using Waystone.Monads.Options.Extensions;
global using Waystone.Monads.Results;
global using Waystone.Monads.Results.Extensions;
global using Waystone.Monads.Results.Errors;

Your first Option<T>

Option<T> says a value might not be there. Instead of returning null and hoping the caller checks, you return a type that cannot be read without handling both cases.

Match is the way out. It takes one function for each case and returns a plain value, so there is no state left to forget about.

Your first Result<T, E>

Result<T, E> says the work might fail. The failure is a value you return, not an exception you throw, so the caller sees it in the signature.

Same shape as before. One function for success, one for failure, a plain value out the other end.

Where to go next

Last updated

Was this helpful?