# bind

### CancellableTaskValidation.bind

Namespace: `FsToolkit.ErrorHandling`

Function Signature:

```fsharp
('input -> CancellableTaskValidation<'output, 'Error>)
  -> CancellableTaskValidation<'input, 'Error>
  -> CancellableTaskValidation<'output, 'Error>
```

Chains two `CancellableTaskValidation` computations using **monadic** (short-circuit) semantics. If the first computation returns an `Error`, the binder function is not called and the error is propagated immediately.

Note: Unlike [`apply`](/fstoolkit-errorhandling/fstoolkit.errorhandling.icedtasks/index-1/apply.md) or [`map2`](/fstoolkit-errorhandling/fstoolkit.errorhandling.icedtasks/index-1/map2.md), `bind` does **not** accumulate multiple errors — it short-circuits on the first failure. For error accumulation, use the applicative operators or the `cancellableTaskValidation` CE with `and!`.

### Examples

Note: Many use-cases requiring `bind` operations can also be solved using [the `cancellableTaskValidation` computation expression](/fstoolkit-errorhandling/fstoolkit.errorhandling.icedtasks/index-1/ce.md).

#### Example 1

Sequentially validating a user exists before validating their permissions:

```fsharp
let validateUserWithPermissions (userId: UserId) : CancellableTaskValidation<UserWithRole, string> =
    fetchUser userId
    |> CancellableTaskValidation.bind (fun user -> fetchAndValidateRole user)
```

#### Example 2

Chaining validation steps in a pipeline:

```fsharp
let processPayment (request: PaymentRequest) : CancellableTaskValidation<Receipt, PaymentError> =
    validatePaymentRequest request
    |> CancellableTaskValidation.bind authorizePayment
    |> CancellableTaskValidation.bind chargeCard
```

#### Example 3

Using `bind` inside a `cancellableTaskValidation` CE with sequential steps:

```fsharp
let createUser (input: CreateUserInput) : CancellableTaskValidation<UserId, string> =
    cancellableTaskValidation {
        let! validatedEmail = validateEmail input.Email
        // bind is used implicitly here — short-circuits if validateEmail fails
        let! userId = createUserRecord validatedEmail input.Name
        return userId
    }
```


---

# 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/bind.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.
