Repository F# setup
open System
open System.IO
open System.Threading
open System.Threading.Tasks
open Axial
open Axial.Layers
open Axial.Console
open Axial.FileSystem
open Axial.Hosting
open Axial.Hosting.Browser
open Axial.Hosting.Node
open Axial.PlatformService
open Axial.State
open Axial.Telemetry
open Axial.Telemetry.JavaScriptThe Flow Type
A Flow is an immutable, cold description of work. Nothing runs until an execution interprets the description with an environment:
Shared setup
// Setup for the checked examples on this page.
open System
open System.IO
open System.Threading
open System.Threading.Tasks
open Axial
open Axial.Layers
open Axial.Console
open Axial.FileSystem
open Axial.Hosting
open Axial.Hosting.Browser
open Axial.Hosting.Node
open Axial.PlatformService
open Axial.State
open Axial.Telemetry
open Axial.Telemetry.JavaScript
/// Fails the docs test when an example's result differs from the value shown.
let shouldEqual expected actual =
if actual <> expected then failwithf "Expected %A but got %A" expected actual
SystemIOThreadingTasksAxialLayersConsoleFileSystemHostingBrowserNodePlatformServiceStateTelemetryJavaScriptshouldEqual: 'a -> 'a -> unitexpected: 'aactual: 'a(<>): 'T -> 'T -> boolStructural inequality The first parameter. The second parameter. The result of the comparison. 5 <> 5 // Evaluates to false 5 <> 6 // Evaluates to true [1; 2] <> [1; 2] // Evaluates to false
failwithf: Printf.StringFormat<'T,'Result> -> 'TPrint to a string buffer and raise an exception with the given result. Helper printers must return strings. The formatter. The formatted result. See Printf.failwithf (link: ) for examples.
type LoadUserError = UserNotFound of int
type AppEnv = { LoadUser: int -> Result<string, LoadUserError> }
let workflow : Flow<AppEnv, LoadUserError, string> =
flow {
let! loadUser = Flow.envWith _.LoadUser
return! loadUser 42
}
FsLiveDocsGeneratedPage11_4556FC416C2B.LoadUserErrorUserNotFoundintAn abbreviation for the CLI type . Basic Types
FsLiveDocsGeneratedPage11_4556FC416C2B.AppEnvLoadUser: int -> Result<string,LoadUserError>Microsoft.FSharp.Core.FSharpResult`2Helper type for error handling without exceptions. Choices and Results
stringAn abbreviation for the CLI type . Basic Types
workflow: Flow<AppEnv,LoadUserError,string>Axial.Flow`3Represents a cold workflow that reads an environment, returns a typed result, and is executed explicitly through one of its execution members such as ToTask, ToAsync, or RunSynchronously. The type of the environment dependency. The type of the failure value. The type of the success value.
flow: FlowBuilderThe universal flow { } computation expression.
loadUser: int -> Result<string,LoadUserError>Axial.FlowenvWith: ('env -> 'value) -> Flow<'env,'error,'value>Projects one value from the current environment. This is the primary way to access app dependencies, configuration, or request metadata stored in env. The projection runs only when the flow is executed, so constructing the flow is still pure and side-effect free. Prefer small projections over passing a large environment deeper into reusable helpers. A function that extracts a value from the environment. A containing the projected value. let currentTime () = Flow.envWith (fun (environment: BaseRuntime) -> environment.Clock.UtcNow())
_arg1: AppEnvBuilding workflow ran nothing. Each execution supplies an environment and returns an outcome:
let live = { LoadUser = fun id -> Ok $"user {id}" }
let empty = { LoadUser = fun id -> Error(UserNotFound id) }
workflow |> Flow.run live |> shouldEqual (Exit.Success "user 42")
workflow |> Flow.run empty |> shouldEqual (Exit.Failure(Cause.Fail(UserNotFound 42)))
live: AppEnvLoadUser: int -> Result<string,LoadUserError>id: intOkRepresents an OK or a Successful result. The code succeeded with a value of 'T.
empty: AppEnvErrorRepresents an Error or a Failure. The code failed with a value of 'TError representing what went wrong.
UserNotFoundworkflow: Flow<AppEnv,LoadUserError,string>(|>): 'T1 -> ('T1 -> 'U) -> 'UApply a function to a value, the value being on the left, the function on the right The argument. The function. The function result. let doubleIt x = x * 2 3 |> doubleIt // Evaluates to 6
Axial.Flowrun: 'env -> Flow<'env,'error,'value> -> Exit<'value,'error>Runs the workflow and blocks until the final exit is available. The environment used by the workflow. The workflow to run. The final workflow exit. let exit = workflow |> Flow.run environment
shouldEqual: 'a -> 'a -> unitAxial.Exit`2Represents the final outcome of a workflow execution. The type of the success value. The type of the domain-specific failure value.
SuccessThe workflow completed successfully.
FailureThe workflow failed due to a specific cause.
Axial.Cause`1Represents the cause of a failed workflow. The type of the domain-specific failure value.
FailAn expected domain-specific failure.
The three type parameters say what the workflow needs, how it can fail, and what it produces:
| Parameter | Meaning |
|---|---|
'env |
Dependencies supplied when the workflow runs |
'error |
Expected failures the caller can handle |
'value |
The value produced on success |
Aliases such as Flow<'value> and EnvFlow<'env, 'value> abbreviate the same type with unused channels fixed.
In this section
- Reading the type: the three channels, the aliases, and what each alias expands to.
- Creating flows: constructors for values, failures, and interop sources.
- Running flows: executions, outcomes, and boundary conversions.
- The flow builder:
flow { }binding rules for flows, tasks, and results. - Combining flows: sequencing, mapping, and channel transformations.
- Task and async interop: moving between Flow,
Task, andAsync. - Troubleshooting types: the compiler errors produced when channels do not line up.
- Resources: acquiring something that must be released.

