# Operators

### CancellableTaskValidation Infix Operators

Namespace: `FsToolkit.ErrorHandling.Operator.CancellableTaskValidation`

FsToolkit.ErrorHandling provides the standard infix operators for `map` (`<!>`), `apply` (`<*>`), and `bind` (`>>=`) to work with `Result<'a, 'b list>`.

There are also variants of the `map` and `apply` operators (`<!^>` and `<*^>`) that accept `Result<'a, 'b>` (non-list) as the right-hand argument.

### Examples

#### Example 1

Assume that we have following types and functions:

```fsharp
type Latitude = private Latitude of float with
  // float -> CancellableTask<Result<Latitude, string list>>
  static member TryCreate (lat : float) =
    // ...

type Longitude = private Longitude of float with
  // float -> CancellableTask<Result<Longitude, string list>>
  static member TryCreate (lng : float) =
    // ...

type Tweet = private Tweet of string with
  // string -> CancellableTask<Result<Tweet, string list>>
  static member TryCreate (tweet : string) =
    // ...

// Latitude -> Longitude -> Tweet -> CreatePostRequest
let createPostRequest lat long tweet =
  // ...
```

We can make use of the standard operators in the CancellableTaskValidation Operators module to perform the cancellableTaskValidation of the incoming request and capture all the errors as shown below:

```fsharp
open FsToolkit.ErrorHandling.Operator.CancellableTaskValidation

// float -> float -> string -> CancellableTask<Result<CreatePostRequest, string list>>
let validateCreatePostRequest lat lng tweet = 
  createPostRequest
  <!> Latitude.TryCreate lat
  <*> Longitude.TryCreate lng
  <*> Tweet.TryCreate tweet
```

By using the `CancellableTaskValidation` operators instead of the `Result` operators, we collect all the errors:

```fsharp
validateCreatePostRequest 300. 400. ""
// Error
     ["300.0 is a invalid latitude value"
      "400.0 is a invalid longitude value"
      "Tweet shouldn't be empty"]
```

#### Example 2

In the above example, all the `TryCreate` functions return a string list as the error type (`CancellableTask<Result<'a, string list>>`). If these functions instead returned `CancellableTask<Result<'a, string>>` (only a single error), we can use `<*^>` and `<!^>` to get the same result:

```fsharp
open FsToolkit.ErrorHandling.Operator.CancellableTaskValidation

// float -> float -> string -> CancellableTask<Result<CreatePostRequest, string list>>
let validateCreatePostRequest lat lng tweet = 
  createPostRequest
  <!^> Latitude.TryCreate lat
  <*^> Longitude.TryCreate lng
  <*^> Tweet.TryCreate tweet
```


---

# 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://demystifyfp.gitbook.io/fstoolkit-errorhandling/fstoolkit.errorhandling.icedtasks/index-1/operators.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.
