Quick, practical examples of FsFlow in action.

Straightforward Examples

These examples show how to use FsFlow for common tasks without the overhead of a full application setup.

1. Simple Environment Access

Use Flow.read to project a single field from your environment record.

type Config = { ApiUrl: string }

let getUrl =
    flow {
        let! url = Flow.read _.ApiUrl
        return url
    }

let outcome = getUrl |> Flow.run { ApiUrl = "https://api.example.com" }
// outcome = Exit.Success "https://api.example.com"

2. Combining Pure Logic and Async Work

Use flow {} to mix pure Check logic, Async blocks, and other flows.

let validateId id =
    id |> okIf (id > 0) |> orError "Invalid ID"

let fetchUser id =
    async { return { Id = id; Name = "Ada" } }

let workflow id =
    flow {
        let! validId = validateId id
        let! user = fetchUser validId // Binds Async<'T> directly
        return user.Name
    }

let effect = workflow 42 |> Flow.run ()
// effect = Effect<string, string> (ValueTask or Async)

3. Retrying a Flow

Use the Schedule module to add operational policies like retries.

let flakyTask =
    flow {
        // Imagine this calls a flaky API
        return! Task.FromResult (Ok "Success")
    }

let resilientWorkflow =
    flakyTask
    |> Flow.Retry (Schedule.recurs 3)

[`Flow.Retry`](/reference/schedule/m-flowscheduleextensions-flow-retry-static/) will retry up to 3 times if the task fails.

4. Conditional Execution

Since flow {} is a standard F# computation expression, you can use if/then, match, and try/with inside it.

let conditionalWorkflow input =
    flow {
        if String.IsNullOrWhiteSpace input then
            return "No input provided"
        else
            let! processed = processInput input
            return processed
    }

5. Mapping Errors

Use Flow.mapError to translate low-level technical errors into domain-specific failures.

type AppError = DatabaseUnavailable | UserNotFound

let domainWorkflow =
    lowLevelFlow
    |> Flow.mapError (function
        | DbException _ -> DatabaseUnavailable
        | :? KeyNotFoundException -> UserNotFound
        | _ -> DatabaseUnavailable)