Functional Weave
Code in Rust

money.sum

Total a list of monetary amounts, with an explicit currency for the empty case.

1.0.1 · published 2026-10-03 by charlie · Anterra

Pinned by 11 tests, run in TypeScript, Python and Rust.

What it does

The currency argument looks redundant until the list is empty, which is exactly when `reduce` without an initial value throws in production.

1.0.1 adds tests; behaviour unchanged.

For example

  • sum_money(£10.00, £25.50, £0.99, GBP) → £36.49 totals three lines
  • sum_money(, GBP) → £0.00 empty list is zero in the stated currency
  • sum_money(£50.00, -£12.00, GBP) → £38.00 credits reduce the total

The function

The same function in TypeScript, Python and Rust, pinned by the same tests. Pick your language; the choice follows you around the registry.

pub fn sum_money(amounts: &[Money], currency: &str) -> Money
amountsMoney[]
currencystringthe currency of the result, required so an empty list still has one
returnsMoney

Your code names it in one line, in the file that uses it

fune!(money.sum@^1);  // then call sum_money(…)
impl/rust.rs · 18 lines · open · raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

use super::funejson::Value;  ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
use super::money_add::add_money;  ← from money.add ^1.0.0 · built alongside by fune
use super::money_amount::{money, money_from_value, money_to_value, Money};  ← from money.amount ^1.0.0 · built alongside by fune

/// # Panics
/// Panics if any amount is in a different currency.
pub fn sum_money(amounts: &[Money], currency: &str) -> Money {
    let mut total = money(0, currency);
    for amount in amounts {
        total = add_money(&total, amount);
    }
    total
}

pub fn fune_vector(args: &[Value]) -> Value {
    let amounts: Vec<Money> = args[0].as_arr().iter().map(money_from_value).collect();
    money_to_value(&sum_money(&amounts, args[1].as_str()))
}

Install

fune build

With that line in your source, in a Rust project (language rust in fune.project), fune build resolves it and its 2 dependencies, pins them in fune.lock, downloads only the Rust package of each, and builds the code above into your project’s .fune/build, one readable file per capability with a header linking back here. A crate’s build.rs runs it before every compile. Or pin a range in fune.project and build in one step:

fune add money.sum
Download for Rust money.sum-1.0.1-rust.fune · 4,690 bytes sha256 d1ad98afef977334cb8399f18c460b5d99eb1b4700924b6cb54d493b85b9a40c

The manifest, vectors and README with only the Rust implementation. Install it without the registry with fune add ./money.sum-1.0.1-rust.fune, or fetch it from a terminal with fune pull money.sum@1.0.1:rust.

The whole function, every language, is one file too: money.sum-1.0.1.fune, 5,305 bytes, sha256 b10d69d8451e8785f2c24dd1321240ee289aef491bedae6c2419b38984e03a02. It installs into a project of any language.

Customise it in your app

The seams this capability offers. Put a marker directly above a function of your own and fune build wires it into the built code; the package on the registry is not changed, the built file’s header lists it under CUSTOMISED, and fune hooks lists every hook in the project. How hooks work.

before — your function gets the arguments and returns them, changed or not, or throws to refuse the call.

// fune: before money.sum

after — your function gets the result and the arguments, and returns the final result.

// fune: after money.sum

replace — inside this capability’s code only, calls to a dependency go to your function, with the same signature. Other capabilities that use it are unaffected; write in * to replace it everywhere.

// fune: replace money.add in money.sum
// fune: replace money.amount in money.sum

step — your function runs at a numbered point inside the function’s body, receives the in-scope values it names as parameters, and may return replacements. List the points with fune show money.sum --steps.

// fune: step money.sum after <n|label>

Tests

A version published now needs at least 8 tests for every function, and one that expects the error for each function that throws; the registry refuses it otherwise. fune verify --all runs each case in TypeScript, Python and Rust, and a project runs them again with fune verify. This page lists the cases; it does not run them. The exact JSON is vectors.json.

CaseArgumentsExpected
totals three lines £10.00, £25.50, £0.99, GBP → £36.49
empty list is zero in the stated currency , GBP → £0.00
credits reduce the total £50.00, -£12.00, GBP → £38.00
a foreign amount in the list is an error £1.00, $1.00, GBP → error: currency mismatch
one amount is its own total €2.50, EUR → €2.50
an empty list in a zero-decimal currency , JPY → ¥0
credits can take the total below zero £10.00, -£15.00, GBP → -£5.00
ten 10p amounts make exactly one pound £0.10, £0.10, £0.10, £0.10, £0.10, £0.10, £0.10, £0.10, £0.10, £0.10, GBP → £1.00
large totals stay exact up to the largest safe integer £90,071,992,547,400.00, £9.90, £0.01, GBP → £90,071,992,547,409.91
every amount must be in the stated currency, not the first one's €1.00, €2.00, GBP → error: currency mismatch
Show the other 1 test
CaseArgumentsExpected
an invalid currency is refused even for an empty list , gbp → error: ISO 4217

Files

PathBytes
README.md194
impl/python.py284
impl/rust.rs590
impl/typescript.ts276
vectors.json2,272