summaryrefslogtreecommitdiffstats
path: root/lib/balanced_batch.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/balanced_batch.ml')
-rw-r--r--lib/balanced_batch.ml42
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/balanced_batch.ml b/lib/balanced_batch.ml
new file mode 100644
index 0000000..5a64546
--- /dev/null
+++ b/lib/balanced_batch.ml
@@ -0,0 +1,42 @@
1open Prelude
2
3(* Degenerate transactions, which can be applied directly to account
4 hierarchies (because we ideally want no unsafe operations on
5 accounts) *)
6module Make (K : Map_intf.Key) : sig
7 type entry = {
8 dc : Money.Debit_credit.t;
9 commodity : Money.Commodity_id.t;
10 amount : Money.Amount.t;
11 }
12
13 type t
14 type error = Unbalanced
15
16 val make : entry Map.Make(K).t -> (t, error) result
17 val entries : t -> entry Map.Make(K).t
18end = struct
19 type entry = {
20 dc : Money.Debit_credit.t;
21 commodity : Money.Commodity_id.t;
22 amount : Money.Amount.t;
23 }
24
25 type t = entry Map.Make(K).t
26 type error = Unbalanced
27
28 let is_balanced entries =
29 Map.fold entries ~init:Money.Commodity_id.Map.empty
30 ~f:(fun ~key:_ ~data comm_balances ->
31 Map.update comm_balances data.commodity ~f:(fun ocomm_bal ->
32 let comm_bal = Option.value ocomm_bal ~default:Money.Diff.(~$0) in
33 match data.dc with
34 | Money.Debit_credit.Debit -> Money.Diff.(comm_bal +% data.amount)
35 | Money.Debit_credit.Credit -> Money.Diff.(comm_bal -% data.amount)))
36 |> Map.for_all ~f:(fun comm_bal -> Money.Diff.(comm_bal = ~$0))
37
38 let make entries =
39 if not (is_balanced entries) then Error Unbalanced else Ok entries
40
41 let entries entries = entries (* ambiguous? I disagree *)
42end