# Either\<TLeft, TRight>

> [`Tango.Types.Either<TLeft, TRight>`](https://github.com/gabrielschade/Tango/blob/master/Tango/Tango/Types/Either.cs)

This type represents an either value.

Instances of `Either<TLeft, TRight>` encapsulates an value of `TLeft` or `TRight` type as a container and only allow access to these values by the `Match` e `Match2` methods.

A common use of `Either<TLeft, TRight>` is as an alternative to `Option<T>` for dealing with possible missing values. But in this case, `Option<T>.None` is replaced by a `TLeft` value which can contain real and useful information.

Convention dictates that `TRight` is used for success types and `TLeft` is used for fail.

Either values can assume two different states:

* Left  (`IsLeft`) - When it contains a `TLeft` value;
* Right (`IsRight`) - When it contains a `TRight` value.

## Properties

| Name    | Type | Description                                                               |
| ------- | ---- | ------------------------------------------------------------------------- |
| IsLeft  | bool | Returns true when the value is an TLeft value. Otherwise, returns false.  |
| IsRight | bool | Returns true when the value is an TRight value. Otherwise, returns false. |

## Constructors

| Parâmetros   | Retorno                | Descrição                                      |
| ------------ | ---------------------- | ---------------------------------------------- |
| TLeft left   | Either\<TLeft, TRight> | Initialize a new instance with a TLeft value.  |
| TRight right | Either\<TLeft, TRight> | Initialize a new instance with a TRight value. |

## Methods

| Name   | Parameters                                                                                                                                                                                                                                         | Returns | Description                                                                                                                                                              |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Match  | <p>Func\<TRight,TResult> methodWhenRight</p><p>Func\<TLeft, TResult> methodWhenLeft</p>                                                                                                                                                            | TResult | This allows a sophisticated way to apply some method for Either\<TLeft, TRight> values without having to check for the existence of a left or right value.               |
| Match2 | <p>Either\<TLeft2, TRight2> either2</p><p>Func\<TRight, TRight2, T> methodWhenBothRight</p><p>Func\<TRight, TLeft2, T> methodWhenRightLeft</p><p>Func\<TLeft, TRight2, T> methodWhenLeftRight</p><p>Func\<TLeft, TLeft2, T> methodWhenBothLeft</p> | T       | This allows a sophisticated way to apply some method for two different Either\<TLeft, TRight> values without having to check for the existence of a left or right value. |
| Match  | <p>Action\<TRight> methodWhenRight</p><p>Action\<TLeft> methodWhenLeft</p>                                                                                                                                                                         | Unit    | This allows a sophisticated way to apply some method for Either\<TLeft, TRight> values without having to check for the existence of a left or right value.               |
| Match2 | <p>Either\<TLeft2, TRight2> either2</p><p>Action\<TRight, TRight2> methodWhenBothRight</p><p>Action\<TRight, TLeft2> methodWhenRightLeft</p><p>Action\<TLeft, TRight2> methodWhenLeftRight</p><p>Action\<TLeft, TLeft2> methodWhenBothLeft</p>     | T       | This allows a sophisticated way to apply some method for two different Either\<TLeft, TRight> values without having to check for the existence of a left or right value. |

## Operators Overload

| Operator      | Parameter                    | Returns                | Description                                                                                                                         |
| ------------- | ---------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Implicit cast | TLeft left                   | Either\<TLeft, TRight> | Initialize a new instance with a TLeft value.                                                                                       |
| Implicit cast | TRight right                 | Either\<TLeft, TRight> | Initialize a new instance with a TRight value.                                                                                      |
| Implicit cast | Either\<TLeft, TRight>       | Option\<TLeft>         | Creates an Option value by Either.Left property. The results will be Some when Either IsLeft, otherwise the results will be None.   |
| Implicit cast | Either\<TLeft, TRight>       | Option\<TRight>        | Creates an Option value by Either.Right property. The results will be Some when Either IsRight, otherwise the results will be None. |
| Implicit cast | Continuation\<TLeft, TRight> | Either\<TLeft, TRight> | Creates an Either\<TLeft, TRight> from a Continuation\<TLeft, TRight> value.                                                        |

## Usage

You can use an Either value in so many different ways.

### Creating an either value

You can use the constructor to create option values in `IsLeft` or `IsRight` states, according its parameter.

**Constructors**

```csharp
Either<bool, int> valueWithRight = new Either<bool, int>(10); //-> IsRight
Either<bool, int> valueWithLeft = new Either<bool, int>(false); //-> IsLeft
```

You can also use the implict cast feature. Because of it you don't need to worry about any kind of syntax, you just create the value as regular types.

&#x20;**Implict cast**&#x20;

```csharp
Either<bool, int> valueWithRight = 10;   //-> IsRight
Either<bool, int> valueWithLeft = false; //-> IsLeft
```

Through this implicit cast you can creates new option values by using regular return commands, in this particular case is very common to use two different return commands with **different** types.

See the code bellow:

```csharp
private Either<string, int> GetSquareIfEven(int value)
{
  if (value % 2 == 0)
    return value * value;
  else
    return "Odd";
}
```

It can looks weird at first, by having two returns with two different types, but actually both returns will creates a new `Either` value.

But instead of deal with it, **Tango** pass this responsibility to C#.

### Getting value from an either

As `Option` values it is necessary to use the `Match` and `Match2` methods to get the encapsulated value of an Either type.

In this type you can also get the value by an implicit cast to an `Option` of either `TLeft` or `TRight`. In this particular case the option value will receive one of these two types and creates an value according to the `Either` value.

With this implementation is obrigatory to properly handle with all cases about an `Either` value.

&#x20;**Implict cast to an Option**&#x20;

```csharp
Either<bool, int> eitherValue = 10;
Option<int> optionValue = eitherValue;

//optionValue.IsSome = true
```

```csharp
Either<bool, int> eitherValue = 10;
Option<bool> optionValue = eitherValue;

//optionValue.IsSome = false
//optionValue.IsNone = true
```

> &#x20;**WARNING**&#x20;
>
> Even when the implicit cast was made for the correct type the option value can receive an `None` value, because the restrictions of option value.
>
> This case will occurs when the Either encapsulated value is equals to `null` or its `default`.

```csharp
Either<bool, int> eitherValue = 0;
Option<int> optionValue = eitherValue;

//optionValue.IsSome = false
//optionValue.IsNone = true
```

You can also uses the `Match` method. This method receive two different functions as parameters, one for each case: `Right` and `Left` states.

&#x20;**Match with named parameters**

```csharp
Either<bool, int> eitherValue = 10;
int value = eitherValue.Match(
        methodWhenRight: number => number,
        methodWhenLeft: boolean => 0);

//value = 10
```

The first method is executed when the either `IsRight`, because of it, this method receive a `TRight` value as parameter (`int` in this example).

The second method is executed when the either `IsLeft`, because of it, this method receive a `TLeft` value as parameter (`bool` in this example).

These two functions are just regular parameters, so, you can omit the its names.

&#x20;**Match**&#x20;

```csharp
Either<bool, int> eitherValue = 10;
int value = eitherValue.Match(
        number => number,
        boolean => 0);

//value = 10
```

Besides that, you can also apply some transformation in value before got it, like square the value:

```csharp
Either<bool, int> eitherValue = 10;
int value = eitherValue.Match(
        number => number * number,
        boolean => 0);

//value = 100
```

You can also returns any value in `IsLeft` state, in the previous examples were used the zero value, but it isn't obrigatory.

The `Match` method can creates any type of value, even types that are not defined as `TLeft` or `TRight`.

&#x20;**Match to create a new result**&#x20;

```csharp
Either<bool, int> eitherValue = 10;
string value = eitherValue.Match(
        number => number.ToString(),
        boolean => boolean.ToString());

//value = "10"
```

```csharp
Either<bool, int> eitherValue = false;
string value = eitherValue.Match(
        number => number.ToString(),
        boolean => boolean.ToString());

//value = "false"
```

Sometimes is necessary compare more than one `Either` values, this type provides the `Match2` method to compare two different values instead of just one.

This method is so much more complex compared to the previous one, this time, you will have to handle all possible situations.

&#x20;**Match2 when both Either values are in IsRight state**&#x20;

```csharp
Either<bool, int> either = 15;
Either<bool, int> either2 = 10;
int result =
    either.Match2(
                  either2,
                  (value1, value2) => value1 + value2,
                  (value1, value2) => value1,
                  (value1, value2) => value2,
                  (value1, value2) => 0
                );
//result = 25
```

In the previous sample, a sum of two different `Either` values was made. In this particular case, both `Either` was in `IsRight` state, so the first method was executed:

`(value1, value2) => value1 + value2`

In this anonymous method the `value1` parameter received the value from `either` (10) and `value2` from `either2`(15), resulting 25.

The other three methods are executed depending on state of each Either values.

&#x20;**Match2 with IsRight and IsLeft, respectively**

```csharp
Either<bool, int> either = 15;
Either<bool, int> either2 = true;
int result =
    either.Match2(
                  either2,
                  (value1, value2) => value1 + value2,
                  (value1, value2) => value1, // -> Selected
                  (value1, value2) => value2,
                  (value1, value2) => 0
                );
//result = 15
```

&#x20;**Match2 when IsLeft and IsRight, respectively**

```csharp
Either<bool, int> either = false;
Either<bool, int> either2 = 10;
int result =
    either.Match2(
                  either2,
                  (value1, value2) => value1 + value2,
                  (value1, value2) => value1, 
                  (value1, value2) => value2, // -> Selected
                  (value1, value2) => 0
                );
//result = 10
```

&#x20;**Match2 when both Either values are in IsLeft state**&#x20;

```csharp
Either<bool, int> either = false;
Either<bool, int> either2 = true;
int result =
    either.Match2(
                  either2,
                  (value1, value2) => value1 + value2,
                  (value1, value2) => value1,
                  (value1, value2) => value2,
                  (value1, value2) => 0 // -> Selecionado
                );
//result = 0
```

There's an overload of `Match` and `Match2` methods to receive an `Action` as parameter instead of a `Func`.

The fundamentals about `Either values` can be find in [Fundamentals > Either Values](https://github.com/gabrielschade/tango/tree/379cc4a38ae47796971eb875ec66e7dc053a9081/Concepts/Either%20Values.html) section.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gabriel-schade-cardoso.gitbook.io/tango/types/introduction-2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
