-
Notifications
You must be signed in to change notification settings - Fork 15
ValueOrError
SuccincT.Options.ValueOrError
Provides a special-case union of two string values: one representing a value; the other an error. For use in situations where a string return type is needed, by throwing exceptions isn't desirable.
Instances of ValueOrError cannot be created directly using new. As both possible values are of type string, the constructor would need two parameters and messy null passing, a boolean parameters or similar. Instead use the two static methods WithValue() and WithError().
public static ValueOrError WithValue(string value)Creates an instance of ValueOrError holding a value. If value is null, an ArgumentNullException will be thrown.
public static ValueOrError WithError(string error)Creates an instance of ValueOrError holding an error. If error is null, an ArgumentNullException will be thrown.
ValueOrError is a class, not a struct, but it overrides both Equals and the == & != operator pair, so instances use value comparison for equality. The following rules apply to equality:
- If an instance of
ValueOrErrorholds a value, then it will equal another instance if that also hold a value and that value has the same string content. - If an instance of
ValueOrErrorholds an error, then it will equal another instance if that also hold an error and that error has the same string content.
This can be expressed this in code with the following.
var valA = ValueOrError.WithValue("abc");
var valB = ValueOrError.WithValue("abc");
var valC = ValueOrError.WithValue("def");
var errA = ValueOrError.WithError("abc");
var errB = ValueOrError.WithError("abc");
var errC = ValueOrError.WithError("def");
// The following expressions are all true:
valA == valA
valA == valB
valB != valC
valA.Equals(valA)
valA != errA
errA == errA
errA == errB
errB != errC
errA.Equals(errB)ValueOrError uses Succinc<T>'s pattern matching capabilities to perform an action or generate a result according to its value/error state. Two versions of the match method are directly supported by ValueOrError:
public ValueOrErrorMatcher<T> Match()Match() supports the construction of pattern matches and actions (void methods) to invoke upon match. The pattern must be terminated with Exec().
The format of an option match pattern is as follows:
option.Match()
.Value()<optional guard>.Do(value => action on value)
.Error()<optional guard>.Do(error => action on error)
[.Else(option => action when no match) |
.IgnoreElse()]
.Exec()
Value() can take an optional guard of two forms:
.Value().Of(value1).Or(value2).Or(value3)...Do(value => action on value)
.Value().Where(value => boolean expression).Do(value => action on value)
Multiple Value() expressions may be defined. Each is compared in turn again the value (assume there is one) until a match is found. The action is then invoked and no further matching occurs.
Error() can also take an optional guard of two forms:
.Error().Of(value1).Or(value2).Or(value3)...Do(error => action on error)
.Error().Where(value => boolean expression).Do(error => action on error)
Multiple Error() expressions may be defined. Each is compared in turn again the value (assume there is one) until a match is found. The action is then invoked and no further matching occurs.
The Else action is used if no match was found. The ValueOrError itself is passed as a parameter to the associated action. If no action is required when no match occurs, IgnoreElse can be used instead.
If no match is found, and no Else() or IgnoreElse is defined, a SuccincT.PatternMatchers.NoMatchException will be thrown
public ValueOrErrorMatcher<T, TResult> Match<T>()Match<T>() supports the construction of pattern matches and functions returning a TResult to invoke upon match. The pattern must be terminated with Result().
The format of an option match pattern is as follows:
option.Match<T>()
.Value()<optional guard>.Do(value => func resulting in a T))
.Error()<optional guard>.Do(error => func resulting in a T))
.Else(option => no match func resulting in a T)
.Result()
Value() can take an optional guard of two forms:
.Value().Of(value1).Or(value2).Or(value3)...Do(value => func resulting in a T))
.Value().Where(value => boolean expression).Do(value => func resulting in a T))
Multiple Value() expressions may be defined. Each is compared in turn again the value (assume there is one) until a match is found. The function is then invoked and no further matching occurs.
Error() can also take an optional guard of two forms:
.Error().Of(value1).Or(value2).Or(value3)...Do(error => func resulting in a T))
.Error().Where(value => boolean expression).Do(error => func resulting in a T))
Multiple Error() expressions may be defined. Each is compared in turn again the value (assume there is one) until a match is found. The function is then invoked and no further matching occurs.
The Else function is used if no match was found. The option itself is passed as a parameter to the associated function.
If no match is found, and no Else() defined, a SuccincT.PatternMatchers.NoMatchException will be thrown
As an alternative to using an option in a functional style, its value can be directly accessed by more traditional, imperative style C# code. three read-only properties are provided for this purpose. In addition, ToString() is overridden to handle the dual-state nature of its values.
public bool HasValue { get; }**
True if the ValueOrError has a value; false if it's an error.
public string Value { get; }
If HasValue is true, this will return the value held. Otherwise it will throw an InvalidOperationException.
public string Error { get; }
If HasValue is false, this will return the error held. Otherwise it will throw an InvalidOperationException.
public override string ToString()
Returns Value of <the value held> or Error of <the error held> depending on with a value or error is held, respectively.
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