# language-ext
**Repository Path**: tangzhiming/language-ext
## Basic Information
- **Project Name**: language-ext
- **Description**: No description available
- **Primary Language**: C#
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-06-21
- **Last Updated**: 2021-06-21
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README

C# Functional Programming Language Extensions
=============================================
[](https://gitter.im/louthy/language-ext?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
This library uses and abuses the features of C# to provide a functional-programming 'base class library' that, if you squint, can look like
extensions to the language itself. The desire here is to make programming in C# much more reliable and to make the engineer's inertia flow
in the direction of declarative and functional code rather than imperative.
__Author on twitter:__
https://twitter.com/paullouth
## Index
* [Contributing & Code of Conduct](#contributing--code-of-conduct)
* [Nu-get package](#nu-get)
* [Code-gen setup](#code-gen-setup)
* [Unity](#unity)
* [Introduction](#introduction)
* [Getting started](#getting-started)
* [Features](#features)
* [API Reference](https://louthy.github.io/language-ext)
This library started out trying to deal with issues in C#, that after using Haskell and F# started to frustrate me:
* [Poor tuple support](#poor-tuple-support)
* [Null reference problem](#null-reference-problem)
* [Option](#option)
* [Lack of lambda and expression inference](#lack-of-lambda-and-expression-inference)
* [Void isn't a real type](#void-isnt-a-real-type)
* [Mutable lists and dictionaries](#mutable-lists-and-dictionaries)
* [Lists](#lists)
* [List pattern matching](#list-pattern-matching)
* [Maps](#maps)
* [Difficulty in creating immutable record types](#difficulty-in-creating-immutable-record-types)
* [Transformation of immutable types](#transformation-of-immutable-types)
* [`[With]`](#with)
* [Transformation of nested immutable types with Lenses](#transformation-of-nested-immutable-types-with-lenses)
* [`[WithLens]`](#withlens)
* [The awful 'out' parameter](#the-awful-out-parameter)
* [The lack of ad-hoc polymorphism](#ad-hoc-polymorphism)
* [`Num`](#num)
* [`Eq`](#eq)
* [`Ord`](#ord)
* [`Semigroup`](#semigroup)
* [`Monoid`](#monoid)
* [`Monad`](#monad)
* [Transformer types](#transformer-types)
## Reference
#### [API Reference](https://louthy.github.io/language-ext)
#### [Issues that contain documentation and examples](https://github.com/louthy/language-ext/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3A%22examples%20%2F%20documentation%22%20)
## Contributing & Code of Conduct
If you would like to get involved with this project, please first read the [Contribution Guidelines](https://github.com/louthy/language-ext/blob/master/CONTRIBUTING.md) and the [Code of Conduct](https://github.com/louthy/language-ext/blob/master/CODE_OF_CONDUCT.md).
## Nu-get
Nu-get package | Description
---------------|-------------
[LanguageExt.Core](https://www.nuget.org/packages/LanguageExt.Core) | All of the core types and functional 'prelude'. __This is all that's needed to get started__.
[LanguageExt.FSharp](https://www.nuget.org/packages/LanguageExt.FSharp) | F# to C# interop library. Provides interop between the LanguageExt.Core types (like `Option`, `List` and `Map`) to the F# equivalents, as well as interop between core BCL types and F#
[LanguageExt.Parsec](https://www.nuget.org/packages/LanguageExt.Parsec) | Port of the [Haskell parsec library](https://hackage.haskell.org/package/parsec)
[LanguageExt.Rx](https://www.nuget.org/packages/LanguageExt.Rx) | Reactive Extensions support for various types within the Core
[LanguageExt.CodeGen](https://www.nuget.org/packages/LanguageExt.CodeGen) | [Used to generate records, unions, lenses, and `With` functions automagically](https://github.com/louthy/language-ext/wiki/Code-generation).
## Code-gen setup
To use the code-generation features of `language-ext` (which are totally optional by the way), then you must include the [LanguageExt.CodeGen](https://www.nuget.org/packages/LanguageExt.CodeGen) package into your project.
To make the reference **build and design time only** (i.e. your project doesn't gain an additional dependencies because of the code-generator), open up your `csproj` and set the `PrivateAssets` attribute to `all`:
```xml
```
> Obviously, update the `Version` attributes to the appropriate values. Also note that you will probably need the latest VS2019+ for this to work. Even early versions of VS2019 seem to have problems.
There's more information on the code-gen features on [the wiki](https://github.com/louthy/language-ext/wiki/Code-generation)
## Unity
This library seems compatible on the latest (at the time of writing) Unity 2018.2 with __incremental compiler__ (which enables C# 7), so it should work well once Unity has official support for C# 7 on upcoming 2018.3.
In the meanwhile, you can install incremental compiler instead.
If you are concerned about writing functionally and the possible performance overheads then please take a look at [this wiki page](https://github.com/louthy/language-ext/wiki/Performance).
## Introduction
One of the great features of C#6+ is that it allows us to treat static classes like namespaces. This means that we can use static
methods without qualifying them first. That instantly gives us access to single term method names that look exactly like functions
in functional languages. i.e.
```C#
using static System.Console;
WriteLine("Hello, World");
```
This library tries to bring some of the functional world into C#. It won't always sit well with the seasoned C# OO programmer,
especially the choice of camelCase names for a lot of functions and the seeming 'globalness' of a lot of the library.
I can understand that much of this library is non-idiomatic, but when you think of the journey C# has been on, is "idiomatic"
necessarily right? A lot of C#'s idioms are inherited from Java and C# 1.0. Since then we've had generics, closures, Func, LINQ,
async... C# as a language is becoming more and more like a functional language on every release. In fact, the bulk of the new
features are either inspired by or directly taken from features in functional languages. So perhaps it's time to move the C#
idioms closer to the functional world's idioms?
__A note about naming__
One of the areas that's likely to get seasoned C# heads worked up is my choice of naming style. The intent is to try and make
something that _feels_ like a functional language rather than following rules of naming conventions (mostly set out by
the BCL).
There is, however, a naming guide that will keep you in good stead while reading through this documentation:
* Type names are `PascalCase` in the normal way
* The types all have constructor functions rather than public constructors that you instantiate with `new`. They will always
be `PascalCase`:
```C#
Option x = Some(123);
Option y = None;
List items = List(1,2,3,4,5);
Map dict = Map((1, "Hello"), (2, "World"));
```
* Any (non-type constructor) static function that can be used on its own by `using static LanguageExt.Prelude` are `camelCase`.
```C#
var x = map(opt, v => v * 2);
```
* Any extension methods, or anything "fluent" are `PascalCase` in the normal way
```C#
var x = opt.Map(v => v * 2);
```
Even if you disagree with this non-idiomatic approach, all of the `camelCase` static functions have fluent variants, so you never actually have to see the non-standard stuff.
_If you're not using C# 6 yet, then you can still use this library. Anywhere in the docs below where you see a camelCase function
it can be accessed by prefixing with `Prelude.`_
### Getting started
To use this library, simply include `LanguageExt.Core.dll` in your project or grab it from NuGet, and add this to the top of each `.cs` file that needs it:
```C#
using LanguageExt;
using static LanguageExt.Prelude;
```
The namespace `LanguageExt` contains the core types, and `LanguageExt.Prelude` contains the functions that you bring into scope `using static LanguageExt.Prelude`.
### Features
Location | Feature | Description
---------|---------|------------
`Core` | `Arr` | [Immutable array](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Arr_A.htm)
`Core` | `Lst` | [Immutable list](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Lst_A.htm)
`Core` | `Map` | [Immutable map](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Map_K_V.htm)
`Core` | `Map` | [Immutable map with Ord constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Map_OrdK_K_V.htm)
`Core` | `HashMap` | [Immutable hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/HashMap_K_V.htm)
`Core` | `HashMap` | [Immutable hash-map with Eq constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/HashMap_EqK_K_V.htm)
`Core` | `Set` | [Immutable set](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Set_A.htm)
`Core` | `Set` | [Immutable set with Ord constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Set_OrdA_A.htm)
`Core` | `HashSet` | [Immutable hash-set](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/HashSet_A.htm)
`Core` | `HashSet` | [Immutable hash-set with Eq constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/HashSet_EqA_A.htm)
`Core` | `Que` | [Immutable queue](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Que_T.htm)
`Core` | `Stck` | [Immutable stack](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Stck_T.htm)
`Core` | `Option` | [Option monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Option_A.htm) that can't be used with `null` values
`Core` | `OptionAsync` | [OptionAsync monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/OptionAsync_A.htm) that can't be used with `null` values with all value realisation does asynchronously
`Core` | `OptionUnsafe` | [Option monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/OptionUnsafe_A.htm) that can be used with `null` values
`Core` | `Either` | [Right/Left choice monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Either_L_R.htm) that won't accept `null` values
`Core` | `EitherUnsafe` | [Right/Left choice monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/EitherUnsafe_L_R.htm) that can be used with `null` values
`Core` | `EitherAsync` | [EitherAsync monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/EitherAsync_L_R.htm) that can't be used with `null` values with all value realisation done asynchronously
`Core` | `Try` | [Exception handling lazy monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Try_A.htm)
`Core` | `TryAsync` | [Asynchronous exception handling lazy monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/TryAsync_A.htm)
`Core` | `TryOption` | [Option monad with third state](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/TryOption_A.htm) 'Fail' that catches exceptions
`Core` | `TryOptionAsync` | [Asynchronous Option monad with third state](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/TryOptionAsync_A.htm) 'Fail' that catches exceptions
`Core` | `Record` | [Base type for creating record types](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Record_RECORDTYPE.htm) with automatic structural equality, ordering, and hash code calculation.
`Core` | `Lens` | [Well behaved bidirectional transformations](#transformation-of-nested-immutable-types-with-lenses) - i.e. the ability to easily generate new immutable values from existing ones, even when heavily nested.
`Core` | `Reader` | [Reader monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Reader_Env_A.htm)
`Core` | `Writer` | [Writer monad that logs to a `W` constrained to be a Monoid](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Writer_MonoidW_W_A.htm)
`Core` | `State` | [State monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/State_S_A.htm)
`Core` | `Patch` | Uses patch-theory to efficiently calculate the difference (`Patch.diff(list1, list2)`) between two collections of `A` and build a patch which can be applied (`Patch.apply(patch, list)`) to one to make the other (think git diff).
`Parsec` | `Parser` | [String parser monad and full parser combinators library](https://louthy.github.io/language-ext/LanguageExt.Parsec/LanguageExt.Parsec/index.htm#Parser_T)
`Parsec` | `Parser` | [Parser monad that can work with any input stream type](https://louthy.github.io/language-ext/LanguageExt.Parsec/LanguageExt.Parsec/index.htm#Parser_I_O)
`Core` | `NewType` | [Haskell `newtype` equivalent](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/NewType_NEWTYPE_A_PRED.htm) i.e: `class Hours : NewType { public Hours(double value) : base(value) { } }`. The resulting type is: equatable, comparable, foldable, a functor, monadic, and iterable
`Core` | `NumType` | [Haskell `newtype` equivalent but for numeric types](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/NumType_NUMTYPE_NUM_A_PRED.htm) i.e: `class Hours : NumType { public Hours(double value) : base(value) { } }`. The resulting type is: equatable, comparable, foldable, a functor, a monoid, a semigroup, monadic, iterable, and can have basic artithmetic operations performed upon it.
`Core` | `FloatType` | [Haskell `newtype` equivalent but for real numeric types](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/FloatType_SELF_FLOATING_A_PRED.htm) i.e: `class Hours : FloatType { public Hours(double value) : base(value) { } }`. The resulting type is: equatable, comparable, foldable, a functor, a monoid, a semigroup, monadic, iterable, and can have complex artithmetic operations performed upon it.
`Core` | `Nullable` extensions | [Extension methods for `Nullable`](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/NullableExtensions_.htm) that make it into a functor, applicative, foldable, iterable and a monad
`Core` | `Task` extensions | [Extension methods for `Task`](https://louthy.github.io/language-ext/LanguageExt.Core/TaskExtensions_.htm) that make it into a functor, applicative, foldable, iterable and a monad
`Core` | `Validation` | [Validation applicative and monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Validation_FAIL_SUCCESS.htm) for collecting multiple errors before aborting an operation
`Core` | `Validation` | [Validation applicative and monad](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Validation_FAIL_SUCCESS.htm) for collecting multiple errors before aborting an operation, uses the supplied monoid in the first generic argument to collect the failure values.
`Core` | Monad transformers | A higher kinded type (ish)
`Core` | Currying | [Translate the evaluation of a function that takes multiple arguments into a sequence of functions, each with a single argument](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Prelude_.htm#curry<T1,%20T2,%20R>)
`Core` | Partial application | [the process of fixing a number of arguments to a function, producing another function of smaller arity](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Prelude_.htm#par<T1,%20T2,%20R>)
`Core` | Memoization | [An optimization technique used primarily to speed up programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Prelude_.htm#memo<T,%20R>)
`Core` | [Improved lambda type inference](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Prelude_.htm#fun) | `var add = fun( (int x, int y) => x + y)`
`Core` | [`IQueryable` extensions](https://louthy.github.io/language-ext/LanguageExt.Core/QueryExtensions_.htm) |
`Core` | [`IObservable` extensions](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/ObservableExt_.htm) |
## Poor tuple support
I've been crying out for proper tuple support for ages. When this library was created we were no closer (C# 6).
The standard way of creating them is ugly `Tuple.Create(foo,bar)` compared to functional languages where the syntax is often
`(foo,bar)` and to consume them you must work with the standard properties of `Item1`...`ItemN`. Luckily now in C# 7
we can use: `(foo,bar)`. But for those that can't:
```C#
var ab = Tuple("a","b");
```
Now isn't that nice?
Consuming the tuple is now handled using `Map`, which projects the `Item1`...`ItemN` onto a lambda function (or action):
```C#
var name = Tuple("Paul","Louth");
var res = name.Map( (first, last) => $"{first} {last}");
```
Or, you can use a more functional approach:
```C#
var name = Tuple("Paul","Louth");
var res = map( name, (first, last) => $"{first} {last}");
```
This allows the tuple properties to have names, and it also allows for fluent handling of functions that return tuples.
If you are using C#7 then you'll know that the new `Tuple` type is `ValueTuple`. Just like with `Tuple`, language-ext
adds many extensions to the standard BCL `ValueTuple`.
For example:
```C#
var abc = ('a', 'b').Add('c'); // ('a', 'b', 'c')
var abcd = ('a', 'b').Add('c').Add('d'); // ('a', 'b', 'c', 'd')
var abcd5 = ('a', 'b').Add('c').Add('d').Add(5); // ('a', 'b', 'c', 'd', 5)
var sum = (1, 2, 3).Sum(); // 6
var product = (2, 4, 8).Product(); // 64
var flag = ("one", "two", "three").Contains("one"); // true
var str = ("Hello", " ", "World").Concat(); // "Hello World"
var list = (List(1, 2, 3), List(4, 5, 6)).Concat, Lst>(); // [1,2,3,4,5,6]
```
## Null reference problem
`null` must be [the biggest mistake](https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/) in the whole of computer language history. I realise the original designers
of C# had to make pragmatic decisions, it's a shame this one slipped through though. So, what to do about the
"null problem"?
`null` is often used to indicate _no value_; the method called can't produce a value of the type it said
it was going to produce, and therefore it gives you "nothing". The thing is that when _no value_ is passed to
the consuming code, it gets assigned to a variable of type T, the same type that the function said it was going
to return, except this variable now has a timebomb in it. You must continually check if the value is `null`, if
it's passed around it must be checked too.
As we all know it's only a matter of time before a null reference bug crops up because the variable wasn't
checked. It puts C# in the realm of the dynamic languages, where you can't trust the value you're being given.
Functional languages use what's known as an _option type_. In F# it's called `Option`, in Haskell it's called
`Maybe`. In the next section we'll see how it's used.
## Option
`Option` works in a very similar way to `Nullable`, except it works with all types rather than just value
types. It's a `struct` and therefore can't be `null`. An instance can be created by either calling `Some(value)`,
which represents a positive "I have a value" response, or `None`, which is the equivalent of returning `null`.
So why is it any better than returning `T` and using `null`? It seems we can have a non-value response again
right? Yes, that's true, however you're forced to acknowledge that fact and to write code to handle both possible
outcomes because you can't get to the underlying value without acknowledging the possibility of the two states
that the value could be in. This bulletproofs your code. You're also explicitly telling any other programmers that "this method might not return a value, so make sure you deal with that". This explicit declaration is very
powerful.
This is how you create an `Option`:
```C#
var optional = Some(123);
```
To access the value you must check that it's valid first:
```C#
int x = optional.Match(
Some: v => v * 2,
None: () => 0
);
```
An alternative (functional) way of matching is this:
```C#
int x = match( optional,
Some: v => v * 2,
None: () => 0 );
```
Yet another alternative ("fluent") matching method is this:
```C#
int x = optional
.Some( v => v * 2 )
.None( () => 0 );
```
So choose your preferred method and stick with it. It's probably best not to mix styles.
There are also some helper functions to work with default `None` values; you won't see a `.Value` or a
`GetValueOrDefault()` anywhere in this library. This is because `.Value` puts us right back to where we started, and
you may as well not use `Option` in that case. `GetValueOrDefault()` is also just as bad because it can return `null`
for reference types, and depends on how well defined the `struct` type is you're working with.
However, clearly there will be times when you don't need to do anything with the `Some` case. Also, sometimes you just want some code to execute in the `Some` case and not the
`None` case:
```C#
// Returns the Some case 'as is' and 10 in the None case
int x = optional.IfNone(10);
// As above, but invokes a Func to return a valid value for x
int x = optional.IfNone(() => GetAlternative());
// Invokes an Action if in the Some state.
optional.IfSome(x => Console.WriteLine(x));
```
Of course there are functional versions of the fluent version above:
```C#
int x = ifNone(optional, 10);
int x = ifNone(optional, () => GetAlternative());
ifSome(optional, x => Console.WriteLine(x));
```
To smooth out the process of returning `Option` types from methods there are some implicit conversion
operators and constructors:
```C#
// Implicitly converts the integer to a Some of int
Option GetValue()
{
return 1000;
}
// Implicitly converts to a None of int
Option GetValue()
{
return None;
}
// Will handle either a None or a Some returned
Option GetValue(bool select) =>
select
? Some(1000)
: None;
// Explicitly converts a null value to None and a non-null value to Some(value)
Option GetValue()
{
string value = GetValueFromNonTrustedApi();
return Optional(value);
}
// Implicitly converts a null value to None and a non-null value to Some(value)
Option GetValue()
{
string value = GetValueFromNonTrustedApi();
return value;
}
```
It's actually nearly impossible to get a `null` out of a function, even if the `T` in `Option` is a
reference type and you write `Some(null)`. Firstly, it won't compile, but you might think you can do this:
```C#
private Option GetStringNone()
{
string nullStr = null;
return Some(nullStr);
}
```
That will compile, but at runtime will throw a `ValueIsNullException`. If you do either of these (below)
you'll get a `None`.
```C#
private Option GetStringNone()
{
string nullStr = null;
return nullStr;
}
private Option GetStringNone()
{
string nullStr = null;
return Optional(nullStr);
}
```
These are the coercion rules:
Converts from | Converts to
--------------|-------------
`x` | `Some(x)`
`null` | `None`
`None` | `None`
`Some(x)` | `Some(x)`
`Some(null)` | `ValueIsNullException`
`Some(None)` | `Some(None)`
`Some(Some(x))` | `Some(Some(x))`
`Some(Nullable null)` | `ValueIsNullException`
`Some(Nullable x)` | `Some(x)`
`Optional(x)` | `Some(x)`
`Optional(null)` | `None`
`Optional(Nullable null)` | `None`
`Optional(Nullable x)` | `Some(x)`
As well as the protection of the internal value of `Option`, there's protection for the return value
of the `Some` and `None` handler functions. You can't return `null` from those either; an exception will
be thrown.
```C#
// This will throw a ResultIsNullException exception
string res = GetValue(true)
.Some(x => (string)null)
.None((string)null);
```
`null` goes away if you use `Option`.
However, there are times when you may want your `Some` and `None` handlers to return `null`. This is mostly
when you need to use something in the BCL or from a third-party library, so momentarily you need to step
out of your warm and cosy protected optional bubble, but you've got an `Option` that will throw an
exception if you try.
So you can use `matchUnsafe` and `ifNoneUnsafe`:
```C#
string x = matchUnsafe( optional,
Some: v => v,
None: () => null );
string x = ifNoneUnsafe( optional, (string)null );
string x = ifNoneUnsafe( optional, () => GetNull() );
```
And fluent versions:
```C#
string x = optional.MatchUnsafe(
Some: v => v,
None: () => null
);
string x = optional.IfNoneUnsafe((string)null);
string x = optional.IfNoneUnsafe(() => GetNull());
```
That is consistent throughout the library. Anything that could return `null` has the `Unsafe` suffix. That
means that in those unavoidable circumstances where you need a `null`, it gives you and any other programmers
working with your code the clearest possible sign that they should treat the result with care.
### Option monad - gasp! Not the M word!
I know, it's that damn monad word again. They're actually not scary at all, and damn useful. But if you
couldn't care less (or _could_ care less, for my American friends), it won't stop you taking advantage of the
`Option` type. However, `Option` type also implements `Select` and `SelectMany` and is therefore monadic, which also means it can be used in LINQ expressions and much more!
```C#
Option two = Some(2);
Option four = Some(4);
Option six = Some(6);
Option none = None;
// This expression succeeds because all items to the right of 'in' are Some of int
// and therefore it lands in the Some lambda.
int r = match( from x in two
from y in four
from z in six
select x + y + z,
Some: v => v * 2,
None: () => 0 ); // r == 24
// This expression bails out once it gets to the None, and therefore doesn't calculate x+y+z
// and lands in the None lambda
int r = match( from x in two
from y in four
from _ in none
from z in six
select x + y + z,
Some: v => v * 2,
None: () => 0 ); // r == 0
```
This can be great for avoiding the use of `if then else`, because the computation continues as long as the
result is `Some` and bails otherwise. It is also great for building blocks of computation that you can compose
and reuse. Yes, actually compose and reuse, not like OOP where the promise of composability and modularity are
essentially lies.
To take this much further, all of the monads in this library implement a standard "functional set" of functions:
```C#
Sum // For Option it's the wrapped value.
Count // For Option is always 1 for Some and 0 for None.
Bind // Part of the definition of anything monadic - SelectMany in LINQ
Exists // Any in LINQ - true if any element fits a predicate
Filter // Where in LINQ
Fold // Aggregate in LINQ
ForAll // All in LINQ - true if all element(s) fits a predicate
Iter // Passes the wrapped value(s) to an Action delegate
Map // Part of the definition of any 'functor'. Select in LINQ
Lift / LiftUnsafe // Different meaning to Haskell, this returns the wrapped value. Dangerous, should be used sparingly.
Select
SelectMany
Where
```
This makes them into what would be known in Haskell as a Type Class (although more of a catch-all type-class than a set of well-defined type-classes).
* [Option reference](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Option_A.htm)
* [Option extensions reference](https://louthy.github.io/language-ext/LanguageExt.Core/OptionExtensions_.htm)
__Monad transformers__
Monad transformers allow for nested monadic types. Imagine functionality for working with `Seq