Skip to content

Instantly share code, notes, and snippets.

@axce0712
Created November 10, 2023 13:14
Show Gist options
  • Save axce0712/56ba8cc0a9887aef3c6a9cea2add429a to your computer and use it in GitHub Desktop.
Save axce0712/56ba8cc0a9887aef3c6a9cea2add429a to your computer and use it in GitHub Desktop.
Simple ChangeTracking Proto for F#
type Change<'Value> =
| Detached
| Unchanged of 'Value
| Modified of Original: 'Value * Current: 'Value
| Deleted of 'Value
| Added of 'Value
type ChangeTracking<'Id, 'Value when 'Id : comparison> =
private { Changes: Map<'Id, 'Value> }
module ChangeTracking =
let initialState =
{ Changes = Map.empty }
let track (id, value) changeTracker =
let newChanges =
changeTracker.Changes
|> Map.change id (
function
| Some Detached -> Some (Added value)
| Some change -> Some change
| None -> Some (Unchanged value))
{ Changes = newChanges }
let save (id, value) changeTracker =
let newChanges =
changeTracker.Changes
|> Map.change id (
function
| Some Detached -> Some (Added value)
| Some (Unchanged original) when original <> value -> Some (Modified (original, value))
| Some (Unchanged original) -> Some (Unchanged original)
| Some (Modified (original, _)) when original = value -> Some (Unchanged original)
| Some (Modified (original, _)) -> Some (Modified (original, value))
| Some (Deleted original) -> Some (Modified (original, value))
| Some (Added _) -> Some (Added value)
| None -> Some (Added value))
{ Changes = newChanges }
let remove id changeTracker =
let newChanges =
changeTracker.Changes
|> Map.change id (
Option.map (
function
| Detached -> Detached
| Unchanged original -> Deleted original
| Modified (original, _) -> Deleted original
| Deleted original -> Deleted original
| Added _ -> Detached))
{ Changes = newChanges }
open ChangeTracking
initialState
|> track (5, "Foo")
|> save (4, "Baz")
|> save (5, "Qux")
|> remove 5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment