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.JavaScriptTransforming Values
Pure operators transform one pulled value without introducing another effect:
> (FlowStream.fromSeq [ 1..20 ] : FlowStream<int>)
- |> FlowStream.filter (fun value -> value % 2 = 0)
- |> FlowStream.map (fun value -> value * 10)
- |> FlowStream.skip 2
- |> FlowStream.take 3
- |> FlowStream.runCollect
- |> Flow.run ();;val it: Exit<int list,Never> = Success [60; 80; 100]Axial.FlowStreamModulefromSeq: 'value seq -> FlowStream<'env,'error,'value>Creates a stream from a synchronous sequence of values. The sequence of values to be emitted by the stream. A that yields each value from the sequence. FlowStream.fromSeq [1..10] |> FlowStream.runCollect |> Flow.run ()
(..): ^T -> ^T -> ^T seqThe standard overloaded range operator, e.g. [n..m] for lists, seq {n..m} for sequences The start value of the range. The end value of the range. The sequence spanning the range. [1..4] // Evaluates to [1; 2; 3; 4] [1.5..4.4] // Evaluates to [1.5; 2.5; 3.5] ['a'..'d'] // Evaluates to ['a'; 'b'; 'c'; 'd'] [|1..4|] // Evaluates to an array [|1; 2; 3; 4|] { 1..4 } // Evaluates to a sequence [1; 2; 3; 4])
FlowStreamA stream with no environment requirement and no typed failure.
intAn abbreviation for the CLI type . Basic Types
(|>): '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
filter: ('a -> bool) -> FlowStream<'b,'c,'a> -> FlowStream<'b,'c,'a>Keeps values that satisfy a predicate. stream |> FlowStream.filter (fun value -> value > 0)
value: int(%): ^T1 -> ^T2 -> ^T3Overloaded modulo operator The first parameter. The second parameter. The result of the operation. 29 % 5 // Evaluates to 4
(=): 'T -> 'T -> boolStructural equality The first parameter. The second parameter. The result of the comparison. 5 = 5 // Evaluates to true 5 = 6 // Evaluates to false [1; 2] = [1; 2] // Evaluates to true (1, 5) = (1, 6) // Evaluates to false
map: ('v -> 'w) -> FlowStream<'env,'error,'v> -> FlowStream<'env,'error,'w>Transforms the successful values of a stream using the provided function. The function to transform each value. The stream whose values should be transformed. A new stream that yields transformed values. let stream = FlowStream.fromSeq [1; 2; 3] |> FlowStream.map (fun n -> n * 2)
(*): ^T1 -> ^T2 -> ^T3Overloaded multiplication operator The first parameter. The second parameter. The result of the operation. 8 * 6 // Evaluates to 48
skip: int -> FlowStream<'a,'b,'c> -> FlowStream<'a,'b,'c>Skips the first values. stream |> FlowStream.skip 10
take: int -> FlowStream<'a,'b,'c> -> FlowStream<'a,'b,'c>Emits at most values. stream |> FlowStream.take 10
runCollect: FlowStream<'a,'b,'c> -> Flow<'a,'b,'c list>Collects all emitted values into a list. stream |> FlowStream.runCollect
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
FlowStream.choose combines filtering and mapping. FlowStream.indexed, FlowStream.scan, and FlowStream.distinctUntilChangedBy retain only the state needed for
the next result. FlowStream.takeWhile and FlowStream.skipWhile stop or change behavior according to the first matching value.
Effectful transformations
FlowStream.mapFlow runs one Flow for each value and emits its result:
> (FlowStream.fromSeq [ "a"; "b" ] : FlowStream<string>)
- |> FlowStream.mapFlow (fun letter -> Flow.succeed (letter.ToUpperInvariant()))
- |> FlowStream.runCollect
- |> Flow.run ();;val it: Exit<string list,Never> = Success ["A"; "B"]Axial.FlowStreamModulefromSeq: 'value seq -> FlowStream<'env,'error,'value>Creates a stream from a synchronous sequence of values. The sequence of values to be emitted by the stream. A that yields each value from the sequence. FlowStream.fromSeq [1..10] |> FlowStream.runCollect |> Flow.run ()
FlowStreamA stream with no environment requirement and no typed failure.
stringAn abbreviation for the CLI type . Basic Types
(|>): '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
mapFlow: ('a -> Flow<'b,'c,'d>) -> FlowStream<'b,'c,'a> -> FlowStream<'b,'c,'d>Transforms every value with a Flow effect. ids |> FlowStream.mapFlow load
letter: stringAxial.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
ToUpperInvariant: unit -> stringReturns a copy of this object converted to uppercase using the casing rules of the invariant culture. The uppercase equivalent of the current string.
runCollect: FlowStream<'a,'b,'c> -> Flow<'a,'b,'c list>Collects all emitted values into a list. stream |> FlowStream.runCollect
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
FlowStream.tapFlow runs an effect but preserves the original value. The example uses Flow.delay so printing happens when the stream pulls the value, not when the pipeline is constructed:
> let observed = ResizeArray<int>() in
- (FlowStream.fromSeq [ 1; 2 ] : FlowStream<int>)
- |> FlowStream.tapFlow (fun number ->
- Flow.delay (fun () ->
- observed.Add number
- Flow.succeed ()))
- |> FlowStream.map (fun number -> number * 10)
- |> FlowStream.runCollect
- |> Flow.map (fun emitted -> List.ofSeq observed, emitted)
- |> Flow.run ();;val observed: List<int> = seq [1; 2]
val it: Exit<Tuple<int list,int list>,Never> = Success ([1; 2], [10; 20])observed: ResizeArray<int>``.ctor``: unit -> unitInitializes a new instance of the class that is empty and has the default initial capacity.
intAn abbreviation for the CLI type . Basic Types
Axial.FlowStreamModulefromSeq: 'value seq -> FlowStream<'env,'error,'value>Creates a stream from a synchronous sequence of values. The sequence of values to be emitted by the stream. A that yields each value from the sequence. FlowStream.fromSeq [1..10] |> FlowStream.runCollect |> Flow.run ()
FlowStreamA stream with no environment requirement and no typed failure.
(|>): '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
tapFlow: ('a -> Flow<'b,'c,unit>) -> FlowStream<'b,'c,'a> -> FlowStream<'b,'c,'a>Runs an effect for each value before emitting the original value. stream |> FlowStream.tapFlow logValue
number: intAxial.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)
Add: int -> unitAdds an object to the end of the . The object to be added to the end of the . The value can be for reference types.
succeed: '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
map: ('v -> 'w) -> FlowStream<'env,'error,'v> -> FlowStream<'env,'error,'w>Transforms the successful values of a stream using the provided function. The function to transform each value. The stream whose values should be transformed. A new stream that yields transformed values. let stream = FlowStream.fromSeq [1; 2; 3] |> FlowStream.map (fun n -> n * 2)
(*): ^T1 -> ^T2 -> ^T3Overloaded multiplication operator The first parameter. The second parameter. The result of the operation. 8 * 6 // Evaluates to 48
runCollect: FlowStream<'a,'b,'c> -> Flow<'a,'b,'c list>Collects all emitted values into a list. stream |> FlowStream.runCollect
map: ('value -> 'next) -> Flow<'env,'error,'value> -> Flow<'env,'error,'next>Transforms the successful value of a flow. If the source fails, the is not executed. The original failure cause is preserved, including typed failures, interruption, and defects. Use map for pure value transformations after an effect has succeeded. A function of type 'value -> 'next to transform the successful value. The source flow of type to transform. A new with the transformed success value of type 'next. let flow = Flow.succeed 1 |> Flow.map (fun x -> x + 1)
emitted: int listMicrosoft.FSharp.Collections.ListModuleContains operations for working with values of type . Operations for collections such as lists, arrays, sets, maps and sequences. See also F# Collection Types in the F# Language Guide.
ofSeq: 'T seq -> 'T listBuilds a new list from the given enumerable object. The input sequence. The list of elements from the sequence. let inputs = seq { 1; 2; 5 } inputs |> List.ofSeq Evaluates to [ 1; 2; 5 ]. This is an O(n) operation, where n is the length of the sequence.
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
Both operators remain sequential. They do not pull the next value until the current mapping has completed and the consumer asks for another result. Use Batching and parallelism when mappings should overlap.
Errors and cancellation
FlowStream.mapError changes only the typed failure channel. Defects and interruption remain structurally distinct. When an
operator fails, downstream receives that cause and no further upstream values are pulled.

