https://github.com/atifaziz/Optuple
.NET Standard Library for giving (bool, T) Option-like semantics
https://github.com/atifaziz/Optuple
Last synced: 2 months ago
JSON representation
.NET Standard Library for giving (bool, T) Option-like semantics
- Host: GitHub
- URL: https://github.com/atifaziz/Optuple
- Owner: atifaziz
- License: apache-2.0
- Created: 2018-09-04T07:39:35.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2019-08-29T07:56:49.000Z (over 5 years ago)
- Last Synced: 2024-10-29T11:41:46.510Z (7 months ago)
- Language: C#
- Homepage: https://www.nuget.org/packages/Optuple/
- Size: 67.4 KB
- Stars: 29
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: COPYING.txt
Awesome Lists containing this project
- awesome-csharp - Optuple - .NET Standard Library for giving `(bool, T)` Option-like semantics in a non-obtrusive way; this is, there is no new option type dependency for a library or its users. (Functional programming)
- awesome-dotnet-cn - Optuple - 低调的给出`(bool, T)`类Option句法的.NET标准库,即对于库或其用户来说不会有新的option类型依赖。 (函数式编程)
- awsome-dotnet - Optuple - .NET Standard Library for giving `(bool, T)` Option-like semantics in a non-obtrusive way; this is, there is no new option type dependency for a library or its users. (Functional programming)
- awesome-dotnet - Optuple - .NET Standard Library for giving `(bool, T)` Option-like semantics in a non-obtrusive way; this is, there is no new option type dependency for a library or its users. (Functional programming)
README
# Optuple
Optuple is a .NET Standard library that enables a tuple of Boolean and some
type (`T`), i.e. `(bool, T)`, to have the same semantics as an option type
found in most functional languages.An option type is a discriminated union that either represents the absence of
a value (_none_) or the value that's present (_some_). For example, F# has
such a type that is defined as:```f#
type Option = | None | Some of T
```Optuple, however, does not define any such type. Instead it primarily supplies
extension methods for any `(bool, T)` (like `Match`, `Map` and more) to be
treated like an option type. Suppose a value `x` of type `T`, then
`(true, x)` will be treated like `Some x` and `(false, _)` will
be treated like `None`. Note that in the _none case_, when the first
element is `false`, Optuple completely ignores and discards the second
element.A library that wants to expose optional values needs no dependency on Optuple.
It can just expose `(bool, T)` for some type `T`. The client of the library
can use Optuple independently to get “optional semantics”.## Usage
### Using the library
To use Optuple simply import the following namespace:
```c#
using Optuple;
```An auxiliary namespace is also provided:
```c#
using Optuple.Linq; // LINQ query syntax support
```### Creating optional values
The most basic way to create optional values is to use the static `Option`
class:```c#
var none = Option.None();
var some = Option.Some(42);
```Similarly, a more general extension method is provided, allowing a specified
predicate:```c#
string str = "foo";
var none = Option.SomeWhen(str, s => s == "bar"); // Return None if predicate is violated
var none = Option.NoneWhen(str, s => s == "foo"); // Return None if predicate is satisfied
```Clearly, optional values are conceptually quite similar to nullables. Hence, a
method is provided to convert a nullable into an optional value:```c#
int? nullableWithoutValue = null;
int? nullableWithValue = 2;
var none = nullableWithoutValue.ToOption();
var some = nullableWithValue.ToOption();
```### Retrieving values
When retrieving values, Optuple forces you to consider both cases (that is
if a value is present or not).Firstly, it is possible to check if a value is actually present:
```c#
var isSome = option.IsSome(); //returns true if a value is present
var isNone = option.IsNone(); //returns true if a value is not present
```If you want to check if an option `option` satisfies some predicate, you can
use the`Exists` method.```c#
var isGreaterThanHundred = option.Exists(val => val > 100);
```The most basic way to retrieve a value from an `Option` is the following:
```c#
// Returns the value if present, or otherwise an alternative value (42)
var value = option.Or(42);
```Similarly, the `OrDefault` function simply retrieves the default value for
a given type:```c#
var none = Option.None();
var value = none.OrDefault(); // Value 0
``````c#
var none = Option.None();
var value = none.OrDefault(); // null
```In more elaborate scenarios, the `Match` method evaluates a specified
function:```c#
// Evaluates one of the provided functions and returns the result
var value = option.Match(x => x + 1, () => 42);// Or written in a more functional style (pattern matching)
var value = option.Match(
some: x => x + 1,
none: () => 42
);
```There is a similar `Match` function to simply induce side-effects:
```c#
// Evaluates one of the provided actions
option.Match(x => Console.WriteLine(x), () => Console.WriteLine(42));// Or pattern matching style as before
option.Match(
some: x => Console.WriteLine(x),
none: () => Console.WriteLine(42)
);
```### Transforming and filtering values
A few extension methods are provided to safely manipulate optional values.
The `Map` function transforms the inner value of an option. If no value is
present none is simply propagated:```c#
var none = Option.None();
var stillNone = none.Map(x => x + 10);var some = Option.Some(42);
var somePlus10 = some.Map(x => x + 10);
```Finally, it is possible to perform filtering. The `Filter` function returns
none, if the specified predicate is not satisfied. If the option is already
none, it is simply returned as is:```c#
var none = Option.None();
var stillNone = none.Filter(x => x > 10);var some = Option.Some(10);
var stillSome = some.Filter(x => x == 10);
var none = some.Filter(x => x != 10);
```### Helpers as global methods
If you [statically import][static-using] `OptionModule`:
```c#
using static Optuple.OptionModule;
```it will make the following common methods available for use without type
qualification:- `Some`
- `None<>`
- `SomeWhen`
- `NoneWhen`This permits you to, for example, simply write `Some(42)` and `None()`
instead of `Option.Some(42)` and `None()`, respectively.### Enumerating options
[comment]: # (Move somewhere?!)
Although options deliberately don't act as enumerables, you can easily convert
an option to an enumerable by calling the `ToEnumerable()` method:```c#
var enumerable = option.ToEnumerable();
```By importing the `Optuple.Collections` namespace, you also get the following
extension methods for sequences (`IEnumerable<>`) that are like their LINQ
counterparts but return an option:- `FirstOrNone`: like [`FirstOrDefault`][FirstOrDefault] but returns an option
- `LastOrNone`: like [`LastOrDefault`][LastOrDefault] but returns an option
- `SingleOrNone`: like [`SingleOrDefault`][SingleOrDefault] but returns an option[FirstOrDefault]: https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.firstordefault
[LastOrDefault]: https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.lastordefault
[SingleOrDefault]: https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.singleordefaultThen there is:
- `Filter`, which given a sequence of options, will return a sequence of _x_
values from those options in the original sequence that are _some x_.
- `ListAll`, which given a sequence of options, will return _some list of
x_ if all options in the original sequence are _some x_; otherwise it returns
_none list_.### Working with LINQ query syntax
Optuple supports LINQ query syntax, to make the above transformations
somewhat cleaner.To use LINQ query syntax you must import the following namespace:
```c#
using Optuple.Linq;
```This allows you to do fancy stuff such as:
```c#
var personWithGreenHair =
from person in FindPersonById(10)
from hairstyle in GetHairstyle(person)
from color in ParseStringToColor("green")
where hairstyle.Color == color
select person;
```In general, this closely resembles a sequence of calls to `FlatMap` and
`Filter`. However, using query syntax can be a lot easier to read in complex
cases.### Equivalence and comparison
Two optional values are equal if the following is satisfied:
* The two options have the same type
* Both are none, both contain null values, or the contained values are equal---
Credit: A large portion of this documentation was dervied from that of the
project [Optional]. Thank you, [Nils Lück][nlkl]![Optional]: https://www.nuget.org/packages/Optional/
[nlkl]: https://github.com/nlkl
[static-using]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-static