blob: 5a64546df45431bc433b7517f46a1f1e39d414bd (
about) (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
open Prelude
(* Degenerate transactions, which can be applied directly to account
hierarchies (because we ideally want no unsafe operations on
accounts) *)
module Make (K : Map_intf.Key) : sig
type entry = {
dc : Money.Debit_credit.t;
commodity : Money.Commodity_id.t;
amount : Money.Amount.t;
}
type t
type error = Unbalanced
val make : entry Map.Make(K).t -> (t, error) result
val entries : t -> entry Map.Make(K).t
end = struct
type entry = {
dc : Money.Debit_credit.t;
commodity : Money.Commodity_id.t;
amount : Money.Amount.t;
}
type t = entry Map.Make(K).t
type error = Unbalanced
let is_balanced entries =
Map.fold entries ~init:Money.Commodity_id.Map.empty
~f:(fun ~key:_ ~data comm_balances ->
Map.update comm_balances data.commodity ~f:(fun ocomm_bal ->
let comm_bal = Option.value ocomm_bal ~default:Money.Diff.(~$0) in
match data.dc with
| Money.Debit_credit.Debit -> Money.Diff.(comm_bal +% data.amount)
| Money.Debit_credit.Credit -> Money.Diff.(comm_bal -% data.amount)))
|> Map.for_all ~f:(fun comm_bal -> Money.Diff.(comm_bal = ~$0))
let make entries =
if not (is_balanced entries) then Error Unbalanced else Ok entries
let entries entries = entries (* ambiguous? I disagree *)
end
|