From 86d3f0ab526899e27c6d7b9aa6fb71b17b75e6d5 Mon Sep 17 00:00:00 2001 From: Ruben Bartelink Date: Thu, 16 Nov 2023 23:56:51 +0000 Subject: [PATCH] Remove Accumulator --- DOCUMENTATION.md | 6 ++---- samples/Store/Domain/Cart.fs | 42 ------------------------------------ 2 files changed, 2 insertions(+), 46 deletions(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index cc3cd52f7..42f17f757 100755 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -1363,7 +1363,7 @@ which can then summarize the overall transaction. ### Idiomatic approach - composed method based on side-effect free functions There's an example of such a case in the -[Cart's Domain Service](https://github.com/jet/equinox/blob/master/samples/Store/Domain/Cart.fs#L128): +[Cart's Domain Service](https://github.com/jet/equinox/blob/master/samples/Store/Domain/Cart.fs#L106): ```fsharp let interpretMany fold interpreters (state: 'state): 'state * 'event[] = @@ -1392,9 +1392,7 @@ _NOTE: This is an example of an alternate approach provided as a counterpoint - there's no need to read it as the preceding approach is the recommended one is advised as a default strategy to use_ -As illustrated in [Cart's Domain -Service](https://github.com/jet/equinox/blob/master/samples/Store/Domain/Cart.fs#L99), -an alternate approach is to encapsulate the folding (Equinox in V1 exposed an +An alternate approach is to encapsulate the folding (Equinox in V1 exposed an interface that encouraged such patterns; this was removed in two steps, as code written using the idiomatic approach is [intrinsically simpler, even if it seems not as Easy](https://www.infoq.com/presentations/Simple-Made-Easy/) at diff --git a/samples/Store/Domain/Cart.fs b/samples/Store/Domain/Cart.fs index bc5b4ee3e..b6dc8630b 100644 --- a/samples/Store/Domain/Cart.fs +++ b/samples/Store/Domain/Cart.fs @@ -103,40 +103,6 @@ let interpret command (state: Fold.State) = | SyncItem (Context c, skuId, None, w) -> yield! maybePropChanges c skuId w |] -#if ACCUMULATOR -// This was once part of the core Equinox functionality, but was removed in https://github.com/jet/equinox/pull/184 -// it remains here solely to serve as an example; the PR details the considerations leading to this conclusion - -/// Maintains a rolling folded State while Accumulating Events pended as part of a decision flow -type Accumulator<'event, 'state>(fold: 'state -> 'event[] -> 'state, originState: 'state) = - let accumulated = ResizeArray<'event>() - - /// The Events that have thus far been pended via the `decide` functions `Execute`/`Decide`d during the course of this flow - member _.Accumulated: 'event[] = - accumulated.ToArray() - - /// The current folded State, based on the Stream's `originState` + any events that have been Accumulated during the the decision flow - member _.State: 'state = - accumulated |> fold originState - - /// Invoke a decision function, gathering the events (if any) that it decides are necessary into the `Accumulated` sequence - member x.Transact(interpret: 'state -> 'event[]): unit = - interpret x.State |> accumulated.AddRange - /// Invoke an Async decision function, gathering the events (if any) that it decides are necessary into the `Accumulated` sequence - member x.Transact(interpret: 'state -> Async<'event[]>): Async = async { - let! events = interpret x.State - accumulated.AddRange events } - /// Invoke a decision function, while also propagating a result yielded as the fst of an (result, events) pair - member x.Transact(decide: 'state -> 'result * 'event[]): 'result = - let result, newEvents = decide x.State - accumulated.AddRange newEvents - result - /// Invoke a decision function, while also propagating a result yielded as the fst of an (result, events) pair - member x.Transact(decide: 'state -> Async<'result * 'event[]>): Async<'result> = async { - let! result, newEvents = decide x.State - accumulated.AddRange newEvents - return result } -#else let interpretMany fold interpreters (state: 'state): 'state * 'event[] = let mutable state = state let events = [| @@ -145,21 +111,13 @@ let interpretMany fold interpreters (state: 'state): 'state * 'event[] = yield! events state <- fold state events |] state, events -#endif type Service internal (resolve: CartId -> Equinox.Decider) = member _.Run(cartId, optimistic, commands: Command seq, ?prepare): Async = let interpret state = async { match prepare with None -> () | Some prep -> do! prep -#if ACCUMULATOR - let acc = Accumulator(Fold.fold, state) - for cmd in commands do - acc.Transact(interpret cmd) - return acc.State, acc.Accumulated } -#else return interpretMany Fold.fold (Seq.map interpret commands) state } -#endif let decider = resolve cartId let opt = if optimistic then Equinox.LoadOption.AnyCachedValue else Equinox.LoadOption.RequireLoad decider.Transact(interpret, opt)