Reference

Either and Unit

Package Trax.CoreNamespace Trax.Core.FunctionalSource Either.cs, Unit.cs

Either<TLeft, TRight> is a value on one of two tracks: Left, which a train uses for the exception that switched it to the failure track, or Right, the result. Junctions() returns Task<Either<Exception, TReturn>> and RunEither hands it to the caller. Unit is the value of a junction or train that produces nothing.

Signatures

namespace Trax.Core.Functional;
 
public enum EitherStatus : byte
{
    IsBottom = 0,
    IsLeft = 1,
    IsRight = 2,
}
 
public readonly struct Either<TLeft, TRight> : IEquatable<Either<TLeft, TRight>>
{
    public EitherStatus State { get; }
    public bool IsLeft { get; }
    public bool IsRight { get; }
    public bool IsBottom { get; }
 
    public static Either<TLeft, TRight> Left(TLeft value);
    public static Either<TLeft, TRight> Right(TRight value);
    public static implicit operator Either<TLeft, TRight>(TLeft value);
    public static implicit operator Either<TLeft, TRight>(TRight value);
    public static explicit operator TRight(Either<TLeft, TRight> either);
    public static explicit operator TLeft(Either<TLeft, TRight> either);
 
    public TResult Match<TResult>(Func<TRight, TResult> Right, Func<TLeft, TResult> Left, Func<TResult>? Bottom = null);
    public void Match(Action<TRight> Right, Action<TLeft> Left, Action? Bottom = null);
    public Unit IfRight(Action<TRight> action);
    public Unit IfLeft(Action<TLeft> action);
    public Either<TRight, TLeft> Swap();
    public TRight ValueUnsafe();
}
 
public readonly struct Unit : IComparable<Unit>, IEquatable<Unit>
{
    public static readonly Unit Default;
}

Members

MemberDescription
StateWhich side holds the value: EitherStatus.IsLeft, IsRight, or IsBottom for default(Either<TLeft, TRight>), which holds none
IsLeft, IsRight, IsBottomState as a flag
Left(value), Right(value)An Either on that side. Throw ArgumentNullException for null: neither side holds null.
Implicit conversionsA TLeft or a TRight converts to an Either, so a junction chain can return either one where an Either is expected
Explicit conversions(TRight)either and (TLeft)either read a side, and throw InvalidCastException when the value is on the other side
Match(Right, Left, Bottom)Runs the function or action for the side that holds the value. Throws InvalidOperationException for a bottom value when no Bottom is given.
IfRight(action), IfLeft(action)Runs the action only when the value is on that side; returns Unit
Swap()The same value on the other side. A bottom value stays bottom.
ValueUnsafe()The right value, or default when the value is not on the right. Read the left value with Swap().ValueUnsafe().
Unit.DefaultThe one Unit value. Every Unit equals every other.

Two Either values are equal when they are on the same side and their values are equal. ToString() writes Right(value), Left(value) or Bottom.

Example

using Trax.Core.Functional;
 
Either<Exception, int> result = 42;
 
var text = result.Match(Right: value => $"got {value}", Left: error => error.Message);
 
if (result.IsLeft)
    Console.WriteLine(result.Swap().ValueUnsafe().Message);

See also