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.JavaScriptRunning Flows
Creating a Flow does not execute it. Start it explicitly at a boundary, and read the outcome from the
Exit<'value, 'error> it returns:
> let workflow () : Flow<string> = Flow.succeed "Hello";;
> Flow.run () (workflow ());;
> match Flow.run () (workflow ()) with Exit.Success value -> value | Exit.Failure cause -> Cause.prettyPrint string cause;;val it: Exit<string,Never> = Success "Hello"
val it: string = "Hello"workflow: unit -> Flow<string>FlowA flow that requires no environment and cannot fail with a typed error.
stringAn abbreviation for the CLI type . Basic Types
Axial.Flowsucceed: 'value -> Flow<'env,'error,'value>Same as ok. The value to wrap in a successful flow. A flow that always succeeds with the provided value. let result = Flow.succeed 42 |> Flow.run () // result = Success 42
run: '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
Axial.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.
value: stringFailureThe workflow failed due to a specific cause.
cause: Cause<Never>Axial.CauseprettyPrint: ('error -> string) -> Cause<'error> -> stringPretty prints a cause tree for diagnostics.
string: 'T -> stringConverts the argument to a string using ToString. For standard integer and floating point values and any type that implements IFormattable, ToString conversion uses CultureInfo.InvariantCulture. The input value. The converted string. string 'A' // evaluates to "A" string 0xff // evaluates to "255" string -10 // evaluates to "-10"
Flow.run blocks until the Exit is available. Flow.startTask starts the work at once and returns a task to await,
and Flow.toAsync returns an async that starts nothing until it is run:
> let mutable started = 0;;
> let counted () : Flow<int> = Flow.delay (fun () -> started <- started + 1; Flow.ok started);;
> let cold = Flow.toAsync () (counted ()) in started;;
> (Flow.startTask () (counted ())).Result;;
> Flow.toAsync () (counted ()) |> Async.RunSynchronously;;val started: int = 0
val it: int = 0
val it: Exit<int,Never> = Success 1
val it: Exit<int,Never> = Success 2started: intcounted: unit -> Flow<int>FlowA flow that requires no environment and cannot fail with a typed error.
intAn abbreviation for the CLI type . Basic Types
Axial.Flowdelay: (unit -> Flow<'env,'error,'value>) -> Flow<'env,'error,'value>Defers flow construction until execution time. A function that returns the flow to execute. Recursive calls deferred here are consumed by the executor without growing a chain of parent tasks. Work that must run after the recursive call still needs storage until that call finishes. A flow that lazily evaluates the factory when executed. let flow = Flow.delay (fun () -> Flow.succeed 42)
(+): ^T1 -> ^T2 -> ^T3Overloaded addition operator The first parameter. The second parameter. The result of the operation. 2 + 2 // Evaluates to 4 "Hello " + "World" // Evaluates to "Hello World"
ok: 'value -> Flow<'env,'error,'value>Creates a successful synchronous flow. The value to wrap in a successful flow. A flow that always succeeds with the provided value.
cold: Async<Exit<int,Never>>toAsync: 'env -> Flow<'env,'error,'value> -> Async<Exit<'value,'error>>Builds a cold async that runs the workflow when it is started. Nothing executes until the returned async is run. The environment used by the workflow. The workflow to describe. A cold async that completes with the workflow exit. let handle = workflow |> Flow.toAsync environment
Result: Exit<int,Never>Gets the result value of this . The result value of this , which is of the same type as the task's type parameter. The task was canceled. The collection contains a object. -or- An exception was thrown during the execution of the task. The collection contains information about the exception or exceptions.
startTask: 'env -> Flow<'env,'error,'value> -> Task<Exit<'value,'error>>Starts the workflow immediately and returns a task handle for its final exit. The work is already in flight when this returns. Use Flow.toAsync for a cold handle. The environment used by the workflow. The workflow to start. A task that completes with the workflow exit. let running = workflow |> Flow.startTask environment
(|>): '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
Microsoft.FSharp.Control.FSharpAsyncHolds static members for creating and manipulating asynchronous computations. See also F# Language Guide - Async Workflows. Async Programming
RunSynchronously: Async<'T> * int option * CancellationToken option -> 'TRuns the asynchronous computation and await its result. If an exception occurs in the asynchronous computation then an exception is re-raised by this function. If no cancellation token is provided then the default cancellation token is used. The computation is started on the current thread if is null, has of true, and no timeout is specified. Otherwise the computation is started by queueing a new work item in the thread pool, and the current thread is blocked awaiting the completion of the computation. The timeout parameter is given in milliseconds. A value of -1 is equivalent to . The computation to run. The amount of time in milliseconds to wait for the result of the computation before raising a . If no value is provided for timeout then a default of -1 is used to correspond to . The cancellation token to be associated with the computation. If one is not supplied, the default cancellation token is used. The result of the computation. Starting Async Computations printfn "A" let result = async { printfn "B" do! Async.Sleep(1000) printfn "C" 17 } |> Async.RunSynchronously printfn "D" Prints "A", "B" immediately, then "C", "D" in 1 second. result is set to 17.
The name states when work begins. to* builds a description and starts nothing, start* begins execution
immediately and hands back a handle, and run executes to completion:
| Entry point | Starts work? |
|---|---|
Flow.run / RunSynchronously |
Yes, and blocks until the Exit is available |
Flow.startTask / StartAsTask / StartAsValueTask |
Yes: the work is already running when it returns |
Flow.toAsync / ToAsync |
No: nothing runs until the returned async is started |
The members take an optional cancellationToken for interop callers; the module functions take none, which keeps the
common path short. Use Flow.timeout to bound how long a workflow may run. On Fable, use ToAsync.
Passing an already-cancelled token to a member ends the run with Cause.Interrupt, not a value or a typed error:
Show page setup
// Setup for the checked example on this page.
open System.Threading
open System.Threading.Tasks
open Axial
/// Fails the docs test when an example's result differs from the value shown.let waitForever () : Flow<string> =
Flow.fromTask (fun token ->
task {
do! Task.Delay(Timeout.InfiniteTimeSpan, token)
return "never"
})
let interrupted = new CancellationTokenSource()
interrupted.Cancel()
match (waitForever ()).RunSynchronously((), interrupted.Token) with
| Exit.Failure Cause.Interrupt -> ()
| other -> failwithf "expected interruption, got %A" other
waitForever: unit -> Flow<string>FlowA flow that requires no environment and cannot fail with a typed error.
stringAn abbreviation for the CLI type . Basic Types
Axial.FlowfromTask: (CancellationToken -> Task<'value>) -> Flow<'env,'error,'value>Creates a flow from a cancellable task factory. The factory runs on each execution and receives the runtime's cancellation token, so the flow stays cold and cancellable. Thrown exceptions are recorded as defects (Cause.Die). Use attemptTask when expected exceptions should enter the typed error channel. Starts the operation, observing the supplied cancellation token. .NET only let flow = Flow.fromTask (fun token -> client.GetStringAsync(url, token))
token: CancellationTokentask: TaskBuilderBuilds a task using computation expression syntax.
System.Threading.Tasks.TaskRepresents an asynchronous operation.
Delay: TimeSpan * CancellationToken -> TaskCreates a cancellable task that completes after a specified time interval. The time span to wait before completing the returned task, or to wait indefinitely. A cancellation token to observe while waiting for the task to complete. A task that represents the time delay. represents a negative time interval other than . -or- The argument's property is greater than . The task has been canceled. The provided has already been disposed.
System.Threading.TimeoutContains constants that specify infinite time-out intervals. This class cannot be inherited.
InfiniteTimeSpan: TimeSpanA constant used to specify an infinite waiting period, for methods that accept a parameter.
interrupted: CancellationTokenSourceSystem.Threading.CancellationTokenSourceSignals to a that it should be canceled.
Cancel: unit -> unitCommunicates a request for cancellation. This has been disposed. An aggregate exception containing all the exceptions thrown by the registered callbacks on the associated .
RunSynchronously: unit * CancellationToken option -> Exit<string,Never>Starts the workflow and blocks until the final exit is available. To bound how long the workflow may run, apply Flow.timeout to it: that interrupts the work and waits for its cleanup, where abandoning a blocked wait would leave it running. The environment used by the workflow. The optional cancellation token. Defaults to . The final workflow exit. .NET only
Token: CancellationTokenGets the associated with this . The associated with this . The token source has been disposed.
Axial.Exit`2Represents the final outcome of a workflow execution. The type of the success value. The type of the domain-specific failure value.
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.
InterruptAn administrative signal to stop the workflow (e.g., cancellation).
other: Exit<string,Never>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.
Requires & types
Requires: open Axial; open System.Threading; open System.Threading.Tasks (packages: Axial)val waitForever: unit -> Flow<string>val interrupted: CancellationTokenSourceEvery call starts a fresh execution with its own root scope. Await the returned handle to receive the final Exit.
At interop boundaries, run a Flow directly. Applications normally start their root workflow with App.run.
Related guides
- App reference covers root application execution and lifecycle handles.
- Exit reference covers completed outcomes and boundary conversions.
- Runtime operations tutorial adds timeout, retry, cancellation, and annotations around an execution.

