Skip to content

Instantly share code, notes, and snippets.

@SteveBate
Last active August 29, 2015 14:27
Show Gist options
  • Save SteveBate/ddd189cea95c4995d2fb to your computer and use it in GitHub Desktop.
Save SteveBate/ddd189cea95c4995d2fb to your computer and use it in GitHub Desktop.
A trivial sample exploring the envelope budgeting method in OCaml
open Printf
type envelope = {
name: string;
amount: int;
}
type account = {
name: string;
balance: int;
envelopes: envelope list;
}
let open_account amt =
let envs = [{name = "available"; amount = amt}] in
{ name = "current"; balance = amt; envelopes = envs}
let deposit acc envname amt =
let envs = acc.envelopes |> List.map (fun (e: envelope) ->
match e with
| x when x.name = envname -> { x with amount = x.amount + amt}
| _ -> e
) in
let total = envs |> List.map (fun e -> e.amount) |> List.fold_left(fun x y -> x + y) 0 in
{ acc with balance = total; envelopes = envs }
let print_status (acc: account) =
printf "envelopes:\n";
acc.envelopes |> List.iter (fun (e: envelope) -> printf "%s - %d\n" e.name e.amount);
printf "total: %d\n\n" acc.balance
let add_envelope acc (env: envelope) =
if acc.envelopes |> List.filter(fun (e: envelope) -> e.name = env.name) |> List.length > 0 then raise (Failure (env.name ^ " envelope already exists!"));
let envs = env::acc.envelopes in
let total = envs |> List.map(fun e -> e.amount) |> List.fold_left(fun x y -> x + y) 0 in
{ acc with envelopes = envs; balance = total }
open Account
let acc = open_account 100;;
print_status acc;;
let acc = add_envelope acc { name = "savings"; amount = 25 };;
print_status acc;;
let acc = deposit acc "available" 50;;
print_status acc;;
let acc = add_envelope acc { name = "loans"; amount = 325 };;
print_status acc;;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment