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

Collections

Methods for working with a sequence of Option<T>.

A List<Option<T>> — the results of looking something up once per item — comes up often enough to have its own methods.

Every method here is an extension method, in Waystone.Monads.Options.Extensions. Add the using.

Filter

IEnumerable<Option<T>> Filter<T>(this IEnumerable<Option<T>> source, Predicate<T> predicate)

The sequence version of Filter. Every option that fails the predicate is flipped to None. Nothing is dropped.

List<Option<string>> collection = [
    Option.Some("Hello"),
    Option.Some("World"),
    Option.None<string>()
];

IEnumerable<Option<string>> filtered = collection.Filter(x => x == "Hello");
//                          ^? [Some("Hello"), None, None]

Map

IEnumerable<Option<TOut>> Map<T, TOut>(this IEnumerable<Option<T>> source, Func<T, TOut> map)

The sequence version of Map. The transformation runs on every Some; the Nones pass through untouched.

IEnumerable<Option<string>> mapped = collection.Map(x => $"{x}!");
//                          ^? [Some("Hello!"), Some("World!"), None]

Flatten

Drops the Nones and keeps the values, in order.

Lazy. It walks the source once and composes with the rest of LINQ as you would expect. Nothing runs until you enumerate the result.

This is the sequence version. The Flatten that collapses a single nested Option<Option<T>> is a different method — see Nesting. No receiver is both, so the two never compete.

Collect

For when every value has to be present. You get a Some holding all of them, or a single None if any is missing.

One None anywhere fails the whole call:

This is the opposite of Flatten. Flatten drops what is missing and carries on; Collect treats one missing value as a failure of the whole batch.

It stops at the first None. It never looks at the rest of the source, so anything that would have produced the later elements does not run.

On an empty sequence: you get Some of an empty list, not None. There is nothing missing in it.

The result does not tell you which element was absent. Use Partition on a sequence of Result when you need to know what failed.

Collect is eager, and builds a list as it goes. Do not call it on an unbounded sequence.

CollectAsync

The same job over an IAsyncEnumerable.

It stops pulling from the stream at the first None, so the work behind the later elements never happens. That is the reason to use it rather than reading the whole stream into a list and calling Collect.

Returned Task up to 6.7.0. Returns ValueTask from 7.0.0.

AsEnumerable

Treats a single option as a sequence of nothing or one. Flatten above is built out of it, and it is the way out of the monad into System.Linq.

It is not how you write a LINQ query over an Option. For that — from, select, where, staying inside the Option throughout — see Waystone.Monads.Linq.

FirstOrNone

The first element matching the predicate, or None.

FirstOr

The first match, or the fallback you supplied.

Evaluated eagerly. Use FirstOrElse if the fallback costs something to build.

FirstOrElse

The same, building the fallback only when there is no match.

Last updated

Was this helpful?