-
Notifications
You must be signed in to change notification settings - Fork 15
Either
SuccincT.Unions.Either<TLeft, TRight>
Provides a union of types TLeft and TRight. Either contains a T1 value, or a T2 value; never both nor neither.
Instances of Either<TLeft, TRight> are either created via the overloaded constructor. Because "either" unions can be directly created, TLeft and TRight must be of sufficiently different types for the compiler to be able to choose the correct constructor.
public Either(TLeft value) public Either(TRight value)Using constructors,"either" union instances are created just like any other class:
var e1 = new Either<int, string>(1);
var e2 = new Either<int, string>("2");Either<TLeft, TRight> provides equality via Equals and the == & != operator pair. To be equal, both eithers must have a left value and those values must be equal, or both eithers must have a right value and those values must be equal:
var a = new Either<int, string>(1);
var b = new Either<int, string>(1);
var c = new Either<int, string>(2);
var d = new Either<int, string>("2");
var e = new Either<int, string>("2");
var f = new Either<int, string>("1");
// The following expressions are all true
a == a
a == b
a != c
b != d
c != d
d == e
d != f
a.Equals(b)
d.Equals(e)For details on using Succinc<T>'s own pattern pattern feature with the Either type, see Pattern matching on Either<TLeft, TRight>.
As of v8, C# itself has excellent pattern matching support built in to the language. Either<TLeft, TRight> therefore provides the following deconstruct to allow it's use with position pattern matching:
public void Deconstruct(
out EitherState state,
out TLeft leftValue,
out TRight rightValue);EitherState is an enum with two values, Left and Right. When state == Left, leftValue will contain the value stored in the either and rightValue will be default(TRight). When state == Right, leftValue will be default(TLeft) and rightValue will contain the value stored in the either.
This then allows an either to be pattern matched as follows:
var either = new Either<int, string>(2);
var result = either switch {
(Left, var i, _) => $"Contains int, {i}",
(_, _, var s) => $"Contains string, '{s}'"
};As an alternative to using an either in a functional style, its value can be directly accessed by more traditional, imperative style C# code. Five read-only properties are provided for this purpose:
public bool IsLeft { get; }Returns true if the value is of TLeft; otherwise it returns false.
public TLeft Left { get; }If IsLeft is true, this will return the TLeft value held by the either. Otherwise an InvalidOperationException will be thrown.
public Option<TLeft> TryLeft { get; }If IsLeft is true, this will return the TLeft value held by the either as an Some(Left). Otherwise an Option<TLeft>.None is returned.
public TRight Right { get; }If IsLeft is false, this will return the TRight value held by the "either" union. Otherwise an InvalidOperationException will be thrown.
public Option<TRight> TryRight { get; }If IsLeft is false, this will return the TRight value held by the either as an Some(Right). Otherwise an Option<TRight>.None is returned.
Action/FuncconversionsCyclemethods- Converting between
ActionandFunc - Extension methods for existing types that use
Option<T> - Indexed enumerations
IEnumerable<T>cons- Option-based parsers
- Partial function applications
- Pattern matching
- Pipe Operators
- Typed lambdas
AnyEither<TLeft,TRight>NoneOption<T>Success<T>Union<T1,T2>Union<T1,T2,T3>Union<T1,T2,T3,T4>UnitValueOrError