-
Notifications
You must be signed in to change notification settings - Fork 15
Option_T_
SuccincT.Options.Option<T>
Provides an optional value of type T
. Modelled on F# options. Either contains a T
value, or none
.
Instances of Option<T>
cannot be created directly. Instead they can be created via one of two means:
- Use the two static methods
Option<T>.None()
andOption<T>.Some(T value)
to create anone
or some value, respectively. - A value of
T
can be directly used to create a "some value" option, eg:
Option<int> o = 1;
creates o
as an option containing the value, 1
.
Whilst Option<T>
is a class, not a struct, it overrides both Equals
and the ==
& !=
operator pair to provide value-based equality, as demonstrated by the following code:
var a = Option<int>.Some(1);
var b = Option<int>.Some(1);
var c = Option<int>.Some(2);
var d = Option<int>.None();
var e = Option<int>.None();
// The following expressions are all true
a == a
a == b
a != c
d == e
a.Equals(b)
d.Equals(e)
Option<T>
uses Succinc<T>'s pattern matching capabilities to perform an action or generate a result according to its value. Two versions of the match method are directly supported by Option<T>
:
public OptionMatcher<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()
.Some()<optional guard>.Do(value => action on value)
.None().Do(() => action on no value)
[.Else(option => action on option when no match) |
.IgnoreElse()]
.Exec()
Some()
can take an optional guard of two forms:
.Some().Of(value1).Or(value2).Or(value3)...Do(value => action on value)
.Some().Where(value => boolean expression).Do(value => action on value)
Multiple Some()
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.
Multiple None()
expressions can be defined, but - as None
has no value, the first will match if the option has no value and so subsequent definitions, and associated actions, will always be ignored.
The Else
action is used if no match was found. The option 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 OptionMatcher<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>()
.Some()<optional guard>.Do(value => func resulting in a T)
.None().Do(() => func resulting in a T)
.Else(option => no match func resulting in a T)
.Result()
Some()
can take an optional guard of two forms:
.Some().Of(value1).Or(value2).Or(value3)...Do(value => func resulting in a T)
.Some().Where(value => boolean expression).Do(value => func resulting in a T)
Multiple Some()
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.
Multiple None()
expressions can be defined, but - as None
has no value, the first will match if the option has no value and so subsequent definitions, and associated functions, will always be ignored.
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
For further details see the pattern matching options guide.
As an alternative to using an option in a functional style, its value can be directly accessed by more traditional, imperative style C# code. Two read-only properties are provided for this purpose:
public bool HasValue { get; }
True if the option has a value; else false.
public T Value { get; }
If HasValue
is true, this will return the value held by the option. Otherwise an InvalidOperationException
will be thrown.
public T ValueOrDefault { get; }
If HasValue
is true, this will return the value held by the option. Otherwise it will return default(T)
Option<T>
can be deconstructed to (bool hasValue, T value)
:
var option = Option<int>.Some(1);
var (hasValue, value) = option;
// hasValue == true
// value == 1
var nothing = Option<int>.None();
var (hasValue, value) = nothing;
// hasValue == false
// value == default
Option<T>
provides a number of extension methods for manipulating the value, if present.
public static IEnumerable<T> Choose<T>(this IEnumerable<Option<T>> options)
Returns a new enumeration of options containing just those with a value. Equivalent to executing:
from option in options where option.HasValue select option;
public static Option<T> Flatten<T>(this Option<Option<T>> option)
"Flatterns" (or de-nests) an option of option of T
.
For an Option<Option<T>>
with none
, an Option<T>
with none
is returned.
For an Option<Option<T>>
with a value, an Option<T>
with that same value is returned.
public static Option<TOutput> Map<TInput, TOutput>(this Option<TInput> input,
Func<TInput, TOutput> f)
Maps the input option to an output option, via the supplied function.
For an Option<TInput>
with none
, an Option<TOutput>
with none
is returned.
For an Option<TInput>
with a value, an Option<TOutput>
with the result of applying f(input.Value)
to that value, is returned.
public static Option<T> Or<T>(this Option<T> option, Option<T> anotherOption)
Returns option
if it has a value, otherwise anotherOption
is returned.
public static Option<T> Or<T>(this Option<T> option,
Func<Option<T>> lazyAnotherOption)
Returns option
if it has a value, otherwise lazyAnotherOption()
is called, and the result of that function is returned.
public static Option<T> Some<T>(this T value)
Returns an Option<T>
with Value
set to the value of the item converted. This allows the easy creation of an option from a value, using var
:
var option = "a string".Some();
// option is Option<string> and option.Value == "a string"
Finally, a number of extension methods for IEnumerable<T>
, IDictionary<T>
and for handling casting and null
in general types are provided. See Extension methods for existing types, which use Option<T>
for details.
Action
/Func
conversionsCycle
methods- Converting between
Action
andFunc
- 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
Any
Either<TLeft,TRight>
None
Option<T>
Success<T>
Union<T1,T2>
Union<T1,T2,T3>
Union<T1,T2,T3,T4>
Unit
ValueOrError