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

Collections

Methods for working with a sequence of Result<TOk, TErr>.

A List<Result<TOk, TErr>> — the results of validating a batch, or of calling something once per item — comes up often enough to have its own methods.

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

Flatten

IEnumerable<TOk> Flatten<TOk, TErr>(this IEnumerable<Result<TOk, TErr>> source)

Keeps the successes and drops the failures, in the original order.

List<Result<int, string>> results = [
    Result.Ok<int, string>(1),
    Result.Err<int, string>("bad"),
    Result.Ok<int, string>(3)
];

IEnumerable<int> values = results.Flatten();
//               ^? [1, 3]

FlattenErr

IEnumerable<TErr> FlattenErr<TOk, TErr>(this IEnumerable<Result<TOk, TErr>> source)

The other half. Keeps the failures and drops the successes.

IEnumerable<string> errors = results.FlattenErr();
//                  ^? ["bad"]

Both are lazy and each walks the source once. Call both on the same sequence and you enumerate it twice, which matters when the source is a database query or anything else you would rather not run again. Reach for Partition there.

Partition

Both halves, reading the source once.

Eager. It enumerates the source immediately and hands back two materialised lists.

This is the method to use when you owe the caller every failure, not just the first.

Collect

For when the batch has to succeed as a whole. You get an Ok holding every value, or an Err carrying the first failure.

One failure fails the whole call:

It stops at the first Err. "worse" above is never seen, and anything that would have produced the later elements does not run.

On an empty sequence: you get Ok of an empty list. There is nothing in it to fail.

The values before the failure are discarded. If you need them, use Partition.

Choose between the three by what you owe the caller:

You need
Use

All the values, or one failure

Collect

Every failure, to report them together

Partition

The successes, ignoring failures

Flatten

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 Err, 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 result as a sequence of nothing or one, which is what lets the methods above compose out of LINQ. It discards the error — an Err becomes an empty sequence.

To write a query that stays a Result and keeps the error, see Waystone.Monads.Linq.

Option<T> has the same method, and Flatten on a sequence of either is built out of it.

Last updated

Was this helpful?