Created
November 10, 2023 13:14
-
-
Save axce0712/56ba8cc0a9887aef3c6a9cea2add429a to your computer and use it in GitHub Desktop.
Simple ChangeTracking Proto for F#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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