FSharp.Data.Adaptive

repository·master·Indexed 42 days ago

https://github.com/fsprojects/fsharp.data.adaptive

A functional API for Fable that manages adaptive, changeable data. It provides a system of changeable cells (cval) and adaptive cells (aval) to build reactive data pipelines with incremental updates, including specialized support for adaptive sets, lists, and maps.

Tokens
809
Snippets
4
Records
4
Agent score
4%

What's inside FSharp.Data.Adaptive

  1. What is FSharp.Data.Adaptive and how does it work?

    master

    FSharp.Data.Adaptive is a library for handling changeable ("adaptive") data using functional principles. It allows you to treat adaptive values as if they were immutable data while maintaining efficient, incremental updates under the hood.

    The library distinguishes between two types of container cells:

    1. cval<'T> (Changeable cells): These are the source of truth that can be modified directly by user code. They are prefixed with c for "changeable".
    2. aval<'T> (Adaptive cells): These represent dependent computations. They depend on changeable cells or other adaptive cells but cannot be modified directly. They are prefixed with a for "adaptive".

    Adaptive cells are compatible with changeable cells via inheritance. To retrieve the current value from an adaptive cell and exit the "adaptive world," use AVal.force.

    let changeable = cval 10
    let dependent = changeable |> AVal.map (fun a -> 2 * a)
    
    dependent |> AVal.force // => 20
    transact (fun () -> changeable.Value <- 1)
    dependent |> AVal.force // => 2
  2. How to create dynamic dependencies using AVal.bind

    master

    Dependencies in this library are dynamic. Using AVal.bind, you can create a dependency that only exists if a certain condition is met. If the condition changes such that the dependency is no longer required, no recomputations are performed. This allows for highly efficient branching logic in data pipelines.

    let a = cval "some dependency"
    let b = cval "other input"
    let param = cval 0.5
    
    let result = 
        param 
        |> AVal.bind (fun p -> 
            if p <= 0.33 then a :> aval<_>
            elif p <= 0.66 then b :> aval<_>
            else AVal.constant "invalid"
        )
  3. How to perform incremental updates with adaptive collections

    master

    FSharp.Data.Adaptive provides specialized containers for sets (aset<'T>), lists (alist<'T>), and maps (amap<'Key,'Value>). These containers use incremental recomputation, meaning the cost of updates stays constant regardless of the size of the collection.

    To update a changeable collection, use transact. For example, appending an item to a clist will trigger an efficient, incremental update of any dependent adaptive computations.

    let input = clist [1;2;3]
    let dependent = 
        input 
        |> AList.map (fun v -> v * v) 
        |> AList.fold (+) 0
    
    dependent |> AVal.force // => 14
    transact (fun () -> input.Append 4)
    dependent |> AVal.force // => 30