# Continuation\<TFail, TSuccess>

> [`Tango.Types.Continuation<TFail, TSuccess>`](https://github.com/gabrielschade/Tango/blob/master/Tango/Tango/Types/Continuation.cs)

This type represents a value that allows chainable operations with methods and operations.

Instances of `Continuation<TFail, TSuccess>` contains an instance of `TSuccess` or `TFail` similar to Either values.

However, the `Either` type focus on encapsulate one of two possible values, the `Continuation` is more focused to creates a mechanism of a sophisticated, powerful and idiomatic flow to compose your methods.

Because of the nature of this type, this type doesn't implements the `Match2` method. Instead of it, this class do have the powerful `Then` and `Catch` methods. These methods allows to create a continuous flow to successful and unsucessful operations.

Through these two methods the `Continuation` struct can generate a pipeline with two or more functions by connecting the output of one function as a parameter to the next function in the pipeline flow.

If you have a f function defined by `A -> B` and a g function defined by `B -> C`, you can create a new fg function as `A -> C` connecting the returns of f as a g input.

The `Continuation` values can assume two different states:

* Success - When it contains a `TSuccess` value;
* Fail - When it contains a `TFail` value.

## Properties

| Name      | Type | Description                                                                       |
| --------- | ---- | --------------------------------------------------------------------------------- |
| IsSuccess | bool | Returns true when the result value is a TSuccess value. Otherwise, returns false. |
| IsFail    | bool | Returns true when the result value is a TFail value. Otherwise, returns false.    |

## Constructors

| Parâmetros       | Retorno                        | Descrição                                                                          |
| ---------------- | ------------------------------ | ---------------------------------------------------------------------------------- |
| TSuccess success | Continuation\<TFail, TSuccess> | Initialize a new instance of Continuation\<TFail, TSuccess> with a TSuccess value. |
| TFail fail       | Continuation\<TFail, TSuccess> | Initialize a new instance of Continuation\<TFail, TSuccess> with a TFail value.    |

## Methods

| Name    | Parameters                                                                                                  | Returns                                                                     | Description                                                                                                                                                                                                                                                                                |
| ------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Return  | TSuccess success                                                                                            | Continuation\<TFail, TSuccess>                                              | Initialize a new instance of Continuation\<TFail, TSuccess> with a TSuccess value.                                                                                                                                                                                                         |
| Return  | TFail fail                                                                                                  | Continuation\<TFail, TSuccess>                                              | Initialize a new instance of Continuation\<TFail, TSuccess> with a TFail value.                                                                                                                                                                                                            |
| Match   | <p>Func\<TSuccess,TResult> methodWhenSuccess</p><p>Func\<TFail, TResult> methodWhenFail</p>                 | TSuccess                                                                    | This allows a sophisticated way to apply some method for Continuation\<TFail, TSuccess> values without having to check for the existence of a TFail or TSuccess value.                                                                                                                     |
| Match   | <p>Action\<TSuccess> methodWhenSuccess</p><p>Action\<TFail> methodWhenFail</p>                              | Unit                                                                        | This allows a sophisticated way to apply some method for Continuation\<TFail, TSuccess> values without having to check for the existence of a TFail or TSuccess value.                                                                                                                     |
| Then    | Func\<TSuccess, Continuation\<TFail, TSuccess>> thenMethod                                                  | Continuation\<TFail, TSuccess>                                              | <p>This allows a sophisticated and powerful way to apply some method in order to compose an operation with different functions.</p><p>When the current Continuation\<TFail, TSuccess> IsSuccess the thenMethod is applied. Otherwise, returns itself until encounter a Catch function.</p> |
| Then    | Func\<TSuccess, Continuation\<TFail, TNewSuccess>> thenMethod                                               | Continuation\<TFail, TNewSuccess>                                           | <p>This allows a sophisticated and powerful way to apply some method in order to compose an operation with different functions.</p><p>When the current Continuation\<TFail, TSuccess> IsSuccess the thenMethod is applied. Otherwise, returns itself until encounter a Catch function.</p> |
| Then    | <p>Func\<TParameter, TSuccess, Continuation\<TFail, TNewSuccess>> thenMethod</p><p>TParameter parameter</p> | Continuation\<TFail, TNewSuccess>                                           | <p>This allows a sophisticated and powerful way to apply some method in order to compose an operation with different functions.</p><p>When the current Continuation\<TFail, TSuccess> IsSuccess the thenMethod is applied. Otherwise, returns itself until encounter a Catch function.</p> |
| Catch   | Func\<TFail, Continuation\<TFail, TSuccess>> catchMethod                                                    | Continuation\<TFail, TSuccess>                                              | <p>This allows a sophisticated and powerful way to apply some method in order to compose an operation with different functions.</p><p>When the current Continuation\<TFail, TSuccess> IsFail the catchMethod is applied. Otherwise, returns itself until encounter a Then function.</p>    |
| Catch   | Func\<TFail, Continuation\<TNewFail, TSuccess>> catchMethod                                                 | Continuation\<TNewFail, TSuccess>                                           | <p>This allows a sophisticated and powerful way to apply some method in order to compose an operation with different functions.</p><p>When the current Continuation\<TFail, TSuccess> IsFail the catchMethod is applied. Otherwise, returns itself until encounter a Then function.</p>    |
| Finally | Action finallyMethod                                                                                        | Continuation\<TFail, TSuccess>                                              | <p>This provides a way for code that must be executed once the Continuation\<TFail, TSuccess> has been dealt with to be run whether the was fulfilled successfully or failed.</p><p>This lets you avoid duplicating code in both the Then and Catch methods.</p>                           |
| Finally | Action< Either\<TFail,TSuccess> > finallyMethod                                                             | Continuation\<TFail, TSuccess>                                              | <p>This provides a way for code that must be executed once the Continuation\<TFail, TSuccess> has been dealt with to be run whether the was fulfilled successfully or failed.</p><p>This lets you avoid duplicating code in both the Then and Catch methods.</p>                           |
| Merge   | Func\<TSuccess, Continuation\<TNewFail,TNewSuccess>> mergeMethod                                            | Continuation<( Option\<TFail>, Option\<TNewFail>), (TSuccess, TNewSuccess)> | This allows a powerful way to merge two different Continuations in a single grouped Continuation<(TFail, TNewFail), (TSuccess, TNewSuccess)>.                                                                                                                                              |

## Operators Overload

| Operator              | Parameters                                                                                              | Returns                        | Description                                                                                                     |
| --------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------ | --------------------------------------------------------------------------------------------------------------- |
| Implicit cast         | TSuccess success                                                                                        | Continuation\<TFail, TSuccess> | Initialize a new instance of Continuation\<TFail, TSuccess> with a TSuccess value.                              |
| Implicit cast         | TFail fail                                                                                              | Continuation\<TFail, TSuccess> | Initialize a new instance of Continuation\<TFail, TSuccess> with a TFail value.                                 |
| Implicit cast         | Continuation\<TFail, TSuccess>                                                                          | Option\<TFail>                 | Creates an Option\<TFail> of TFail value by Success property of the Continuation\<TFail, TSuccess> value.       |
| Implicit cast         | Continuation\<TFail, TSuccess>                                                                          | Option\<TSuccess>              | Creates an Option\<TSuccess> of TSuccess value by Success property of the Continuation\<TFail, TSuccess> value. |
| Implicit cast         | Either\<TFail, TSuccess>                                                                                | Continuation\<TFail, TSuccess> | Creates a Continuation\<TFail, TSuccess> from an Either\<TFail, TSuccess> value.                                |
| Greater than (>)      | <p>Continuation\<TFail, TSuccess></p><p>Func\<TSuccess, Continuation\<TFail, TSuccess>> thenMethod</p>  | Continuation\<TFail, TSuccess> | Executes the Then method to create a pipeline flow.                                                             |
| Greater or equal (>=) | <p>Continuation\<TFail, TSuccess></p><p>Func\<TSuccess, Continuation\<TFail, TSuccess>> catchMethod</p> | Continuation\<TFail, TSuccess> | Executes the Catch method to create a pipeline flow.                                                            |

> &#x20;**WARNING**&#x20;
>
> Because of languages limitations the `Continuation` type also implements an overload to (`<`) and (`<=`). But if any of these operators raises a new [`NotSupportedException`](https://msdn.microsoft.com/pt-br/library/system.notsupportedexception%28v=vs.110%29.aspx).

## Usage

You can use a `Continuation` value in so many different ways, usually the creation of a `Continuation` value indicates that a series of functions will be executed as a composition.

### Creating a continuation value

You can use the constructor to create option values in IsFail or IsSuccess states, according its parameter.

**Constructors**

```csharp
Continuation<bool, int> valueWithRight = new Continuation<bool, int>(10); //-> IsSuccess
Continuation<bool, int> valueWithLeft = new Continuation<bool, int>(false); //-> IsFail
```

You can use the `Return` *static* method as well.

**The Return&#x20;*****static*****&#x20;method**

```csharp
Continuation<bool, int> valueWithRight = Continuation<bool, int>.Return(10); //-> IsSuccess
Continuation<bool, int> valueWithLeft = Continuation<bool, int>.Return(false); //-> IsFail
```

Finally the simplest version: implict cast. Because of this feature you don't need to worry about any kind of syntax, you just create the value as regular types.

&#x20;**Implicit cast**

```csharp
Continuation<bool, int> valueWithRight = 10;   //-> IsSuccess
Continuation<bool, int> valueWithLeft = false; //-> IsFail
```

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 Continuation<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 `Continuation` value. But instead of deal with it, **Tango** pass this responsibility to C#.

### Getting value from an continuation

Like the other containers types it is necessary to use the Match method to get the encapsulated value of an `Continuation` type.

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

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

```csharp
Continuation<bool, int> continuationValue = 10;
Option<int> optionValue = continuationValue;

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

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

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

> **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
Continuation<bool, int> continuationValue = 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: `Success` and `Fail` states

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

```csharp
Continuation<bool, int> continuationValue = 10;
int value = continuationValue.Match(
        methodWhenSuccess: success => success,
        methodWhenFail: fail => 0);

//value = 10
```

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

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

Just like Either types does.

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

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

```csharp
Continuation<bool, int> continuationValue = 10;
int value = continuationValue.Match(
         success => success,
         fail => 0);

//value = 10
```

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

```csharp
Continuation<bool, int> continuationValue = 10;
int value = continuationValue.Match(
        success => success * success,
        fail => 0);

//value = 100
```

You can also returns any value in `IsFail` case, 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 TFail or TSuccess.

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

```csharp
Continuation<bool, int> continuationValue = 10;
string value = continuationValue.Match(
        success => success.ToString(),
        fail    => fail.ToString());

//value = "10"
```

```csharp
Continuation<bool, int> continuationValue = true;
string value = continuationValue.Match(
        success => success.ToString(),
        fail    => fail.ToString());

//value = "true"
```

There's no way to compare two different `Continuation` values simultaneously.

## Creating Pipelines

The main value of the `Continuation` type is its capacity to creates clean and sophisticated methods in a pipeline flow by using `Then` and `Catch` methods.

You can encapsulate an integer value in a `Continuation` type and increasing this value in a pipeline flow, as showed by the following example.

&#x20;**Using Then to increase a value**&#x20;

```csharp
Continuation<bool, int> continuation = 5;
Option<int> optionResult = 
    continuation.Then(value => value + 5)
                .Then(value => value + 10);

//optionResult.IsSome = true
//optionResult.Some = 20
```

Initially, the `Continuation` structure contained the value 5, after the first `Then` method the value was increased by 5. It occurs because the encapsulated value is passed as a parameter to the anonymous function described by `value => value + 5`.

Finally, the result of the operation described by the first function (10) is passed to the second anonymous function: `value => value + 10` creating the final result (20).

### When Then isn't executed

When the `Continuation` state `IsFail` neither of the s`Then` methods are executed, it performs just a bypass.

```csharp
Continuation<bool, int> continuation = true;
Option<int> optionResult = 
    continuation.Then(value => value + 5)
                .Then(value => value + 10);

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

In this particular case, you can use the implicit cast feature to get an `Option<bool>` to deal with the fail of the process.

&#x20;**Implicit cast to get the fail result**&#x20;

```csharp
Continuation<bool, int> continuation = true;
Option<bool> optionResult = 
    continuation.Then(value => value + 5)
                .Then(value => value + 10);

//optionResult.IsSome = true
//optionResult.Some = true
```

It is extremely important to notice that there's a real situation where the fail occurs inside the pipeline flow.

When it occurs, all of the `Then` methods described bellow the fail function will be ignored.

&#x20;**When the fail occurs inside the pipeline flow**&#x20;

```csharp
Continuation<bool, int> continuation = 5;
Option<int> optionResult = 
    continuation.Then(value => value + 4)
                .Then(value => 
                      {
                        if( value % 2 == 0)
                            return value + 5;
                        else
                            return false;
                      })
                .Then(value => value + 10);

//optionResult.IsSome = false
```

The previous example shows a function that will creates a fail in the second `Then` method. Because of this, the third `Then` method will performs just a bypass.

You can use the `Catch` method to create methods to deal with `Fail` values.

### Using Catch to deal with fails

When a `Continuation` value contains a `TFail` value it will be ignored by the `Then` methods, that's the main point about `Catch` methods, it a similar method, but in this case, it will execute when the value is `TFail` and will performs a bypass when the value is \`TSuccess´.

```csharp
Continuation<string, int> continuation = 5;
Option<string> optionResult = 
    continuation.Then(value => value + 4)
                .Then(value => 
                      {
                        if( value % 2 == 0)
                            return value + 5;
                        else
                            return "ERROR";
                      })
                .Then(value => value + 10)
                .Catch(fail => $"{fail} catched");

//optionResult.IsSome = true
//optionResult.Some = "ERROR catched"
```

Like the `Then` methods, `Catch` methods are also chainables.

&#x20;**Chained Catches**&#x20;

```csharp
Continuation<string, int> continuation = 5;
Option<string> optionResult = 
    continuation.Then(value => value + 4)
                .Then(value => 
                      {
                        if( value % 2 == 0)
                            return value + 5;
                        else
                            return "ERROR";
                      })
                .Then(value => value + 10)
                .Catch(fail => $"{fail} catched")
                .Catch(message => $"{message} again")
                .Catch(message => $"{message} and again");

//optionResult.IsSome = true
//optionResult.Some = "ERROR catched again and again"
```

### Avoid repeat yourself by using Finally

Sometimes you need to perform an action no matter the `Continuation` value result contains, either a `TFail` or `TSuccess` value. That's the main point about `Finally` methods, it is similar to `Then` and `Catch`, but in this case, it always will execute.

Other notorius difference between `Finally` and the other two methods, is your function parameter. In this case, you can use an Action without any argument. It will be executed and the `Continuation` will be returned to keep the `Continuation` flow.

```csharp
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();

ContinuationModule.Resolve(5)
                  .Then(value => value + 4)
                  .Then(value => value + 10)
                  .Catch(fail => $"{fail} catched")
                  .Finally(() => stopwatch.Stop());
```

Usually the `Finally` method will be the last method of a `Continuation` flow and cause a side effect, so, be careful and keep your eye on it.

Another major difference between this method and the two previous ones, is the fact that you're not able to modify the `Continuation` value. Actually you can access the values by using an overload of Finally that receives an `Action<Either<TFail, TSuccess>>` type as argument.

```csharp
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();

ContinuationModule.Resolve<string, int>(5)
                  .Then(value => value + 4)
                  .Then(value => value + 10)
                  .Catch(fail => $"{fail} catched")
                  .Finally(values => Console.WriteLine(
                      values.Match(
                        number => number.ToString(), 
                        text => text)));
```

Like `Then` and `Catch` methods, `Finally` methods are also chainables.

### Merging two pipelines in a single one

This isn't a common operation, but sometimes you need to merge two different `Continuation` pipelines to complete your use case. In order to make it easy, you can use the `Merge` method.

The argument function of this method receive the entire `Continuation<TFail, TSuccess>` itself as argument and need to return an brand new `Continuation<TNewFail, TNewSuccess>`. The `Merge` return is a new grouped `Continuation<(Option<TFail>, Option<TNewFail>), (TSuccess, TNewSuccess)>`.

This new `Continuation` will be in Success state only when the two previous ones are also in this state, otherwise it will be in Fail state.

You can continue your pipeline, but now, you need to access the `Item` properties, since the values were grouped.

```csharp
Continuation<bool, double> continuation2 = 28.5;
ContinuationModule.Resolve<string, int>(10)
                  .Then(value => value + 2)
                  .Merge(value => continuation2)
                  .Then(values => values.Item1 + values.Item2)
                  .Match(value => value, _ => 0);
```

The new `Continuation` fail types are treated as `Option` values, because there's no guarantee of wich error was occured.

### Chaining methods with pipeline operator

The .NET functional programming language, F#, has an operator to performs these pipeline flows.

This operator are defined by `|>` as pipe-foward and `<|` as reverse pipe or pipe-backward.

With these operators you can perform an elegant pipeline flow like this:

```fsharp
let append1 string1 = string1 + ".append1"
let append2 string1 = string1 + ".append2"

let result1 = "abc" |> append1
printfn "\"abc\" |> append1 gives %A" result1

let result2 = "abc" 
              |> append1
              |> append2
printfn "result2: %A" result2

[1; 2; 3]
|> List.map (fun elem -> elem * 100)
|> List.rev
|> List.iter (fun elem -> printf "%d " elem)
```

Unfortunatelly there's no way to create new operators for your C# code. However, is totally possible to overload the current operators.

With this mindset, **Tango** created some overloads to `>` and `>=` operators to work as pipelines, similar to F# syntax.

Instead of performs a comparison as its default behavior, these operations works as `Then` and `Catch` methods.

Therefore, is fully possible to creates pipelines replacing `Then` for `>` and `Catch` for `>=`.

&#x20;**Replacing Then by `>`**&#x20;

```csharp
Continuation<bool, int> continuation = 5;
Option<int> optionResult = 
    continuation 
    > (value => value + 5)
    > (value => value + 10)
    > (value => value + 10)


//optionResult.IsSome = true
//optionResult.Some = 30
```

&#x20;**Replacing Then and Catch by `>` and `>=`**&#x20;

```csharp
Continuation<string, int> continuation = 5;
Option<string> optionResult = 
    continuation 
    >  (value => value + 4)
    >  (value => 
       {
          if( value % 2 == 0)
              return value + 5;
          else
              return "ERROR";
       })
    >  (value => value + 10)
    >= (fail => $"{fail} catched")
    >= (message => $"{message} again")
    >= (message => $"{message} and again");

//optionResult.IsSome = true
//optionResult.Some = "ERROR catched again and again"
```

> &#x20;**WARNING**&#x20;
>
> There are some limitations by usign operators: 1. Different from F#, is not possible to performs a reverse pipe; 2. It's possible to replace the `Then` and `Catch` methods with the operators only when the resulting value is the same type as the current `Continuation`. There's no way to overload an operator with *generics*.

### When you want to change the Continuation types

Both `Then` and `Catch` methods contains overloads that implements the possibility to create a new `Continuation` type, this way is possible to change the `TSuccess` and `TFail` throughout the pipeline.

```csharp
Continuation<object, int> continuation = 10;
Option<string> optionResult =
    continuation
    .Then<bool>(value => value % 2 == 0)
    .Then<string>(value => value ? "Even" : "Odd");

//optionResult.IsSome = true
//optionResult.Some = "Even"
```

It is important to say that isn't necessary using the *generics* notation: `Then<targetType>`, but you can use it, if you want to.

```csharp
Continuation<string, int> continuation = 1;

Option<double> optionResult =
    continuation
    .Then<bool>(value =>
    {
        if (value % 2 == 0)
            return true;
        else
            return "Life, the Universe and Everything";
    })
    .Catch<double>(message => 42.0);

//optionResult.IsSome = true
//optionResult.Some = 42.0
```

### Get the final result

Usually, after the pipeline you'll need to get the final value, or handle the eventually failures at least.

You can use the `Match` method after all `Then` and `Catch` methods.

```csharp
Continuation<bool, int> continuation = 5;
int integerResult = 
    continuation.Then(value => value + 4)
                .Then(value => 
                      {
                        if( value % 2 == 0)
                            return value + 5;
                        else
                            return false;
                      })
                .Then(value => value + 10)
                .Match(success => success,
                       fail    => 0);

//integerResult  = 0
```


---

# 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-3.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.
