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.
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.
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?