Money

world.money.Money
See theMoney companion object
final case class Money[C <: Currency]

A type-safe representation of a monetary amount, parameterised by its currency.

This is a pure data aggregate combining a numeric world.money.currency.CurrencyValue with a specific Currency C. This design ensures that arithmetic operations between different currencies are prevented at compile time, eliminating a common source of errors.

All operations on Money instances are provided as extension methods in the companion object, maintaining strict separation of data from behaviour.

===How to Create Money Instances===

There are two primary ways to create an instance of Money.

  1. Currency-Specific Syntax (Recommended): The preferred method for creating amounts of a known currency is to use the generated syntax extensions. This provides a clean, readable, and type-safe DSL.
import world.money.*

// Creates a Money instance with the type Money[Currencies.KES.type]
val tenShillings = 10.KES
val fiftyRiyals = 50.50.OMR
  1. Generic Factory Money.apply: For generic programming, where the currency type C is a type parameter, you can use the companion object's apply method. This requires a ValueOf[C] to be available in the implicit scope to provide the runtime currency object.
import world.money.currency.{Currency, Currencies}

def createGenericMoney[C <: Currency](value: BigDecimal)(using ValueOf[C]): Money[C] = {
Money(value) // Uses Money.apply[C](...)
}

val genericKES = createGenericMoney[Currencies.KES.type](100)

Type parameters

C

The singleton type of the currency, constrained to be a subtype of world.money.currency.Currency.

Value parameters

currency

A ValueOf instance that provides the currency object at runtime.

value

The numeric value of the amount.

Attributes

Companion
object
Graph
Supertypes
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all

Members list

Value members

Concrete methods

transparent inline def *(multiplicand: BigDecimal | Long | Int | Double)(using CurrencyMathContext): Money[C]
Extension method from Money

Multiplies this Money amount by a scalar value. Requires a given instance of world.money.currency.CurrencyMathContext.

Multiplies this Money amount by a scalar value. Requires a given instance of world.money.currency.CurrencyMathContext.

Attributes

Note

Using Double can lead to precision inaccuracies.

transparent inline def +(augend: Money[C] | CurrencyValue | BigDecimal | Long | Int | Double)(using CurrencyMathContext): Money[C]
Extension method from Money

Adds another value to this Money instance. Requires a given instance of world.money.currency.CurrencyMathContext.

Adds another value to this Money instance. Requires a given instance of world.money.currency.CurrencyMathContext.

Value parameters

augend

The value to add.

Attributes

Returns

A new Money instance representing the sum.

Note

The value to be added must either be another Money instance of the same currency, or a raw numeric type.

Using Double can lead to precision inaccuracies.

transparent inline def -(subtrahend: Money[C] | CurrencyValue | BigDecimal | Long | Int | Double)(using CurrencyMathContext): Money[C]
Extension method from Money

Subtracts the value of subtrahend from this Money instance. Requires a given instance of world.money.currency.CurrencyMathContext.

Subtracts the value of subtrahend from this Money instance. Requires a given instance of world.money.currency.CurrencyMathContext.

Value parameters

subtrahend

The value to subtract.

Attributes

Returns

A new Money instance representing the difference.

Note

The value to be subtracted must either be another Money instance of the same currency, or a raw numeric type.

Using Double can lead to precision inaccuracies.

transparent inline def /(scalar: BigDecimal | Long | Int | Double)(using CurrencyMathContext): Either[ArithmeticError, Money[C]]
Extension method from Money

Attempts to divide this Money amount by a scalar value. Requires a given instance of world.money.currency.CurrencyMathContext.

Attempts to divide this Money amount by a scalar value. Requires a given instance of world.money.currency.CurrencyMathContext.

Attributes

Returns

An Either containing a errors.ArithmeticError on failure (e.g., division by zero), or the resulting Money instance.

Note

Using Double can lead to precision inaccuracies.

transparent inline def abs: Money[C]
Extension method from Money

Returns the absolute value of this amount.

Returns the absolute value of this amount.

Attributes

transparent inline def add(augend: Money[C] | CurrencyValue | BigDecimal | Long | Int | Double)(using CurrencyMathContext): Money[C]
Extension method from Money

Adds the value of augend to this Money instance. Requires a given instance of world.money.currency.CurrencyMathContext.

Adds the value of augend to this Money instance. Requires a given instance of world.money.currency.CurrencyMathContext.

Value parameters

augend

The value to add.

Attributes

Returns

A new Money instance representing the sum.

Note

The value to be added must either be another Money instance of the same currency, or a raw numeric type.

Using Double can lead to precision inaccuracies.

def allocate(ratios: Seq[BigDecimal])(using context: CurrencyMathContext): Either[ArithmeticError, Seq[Money[C]]]
Extension method from Money

Allocates this money amount proportionally according to the given ratios.

Allocates this money amount proportionally according to the given ratios.

This method divides the total amount among multiple parts based on their relative proportions, handling any remainder by distributing it to the first portions. This ensures that the sum of allocated amounts equals the original amount exactly.

Common use cases include:

  • Splitting bills among multiple parties
  • Distributing tax amounts across line items
  • Allocating revenue shares

Value parameters

context

The math context for division operations.

ratios

A sequence of positive BigDecimal values representing relative proportions. Ratios need not sum to 1; they are normalized internally.

Attributes

Returns

A sequence of Money amounts proportional to the ratios, or an ArithmeticError if allocation fails (e.g., empty ratios, negative ratios, or division errors).

Example
import world.money.*
val total = 100.USD
// Split 100 USD in ratio 3:2:1 (50 USD, 33.33 USD, 16.67 USD)
val shares = total.allocate(Seq(3, 2, 1))
transparent inline def compare(that: Money[C]): Int
Extension method from Money

Compares this Money instance to another of the same currency.

Compares this Money instance to another of the same currency.

Attributes

transparent inline def convertTo[T <: Currency](using provider: ExchangeRateProvider, target: ValueOf[T]): Either[ConversionError, Money[T]]
Extension method from Money

Converts this monetary amount to another currency.

Converts this monetary amount to another currency.

This is the primary method for handling currency conversions. It requires a given world.money.conversion.ExchangeRateProvider to be available in the implicit scope, which is responsible for supplying the necessary conversion rate.

Type parameters

T

The singleton type of the target currency.

Value parameters

provider

An world.money.conversion.ExchangeRateProvider instance that supplies exchange rates for currency conversion.

target

A ValueOf instance for the target currency type T, provided automatically by the compiler.

Attributes

Returns

Right with a Money[T] instance containing the converted amount on success, or Left with an world.money.errors.ConversionError on failure.

Example
import world.money.*
import world.money.conversion.*
import world.money.currency.{Currencies, CurrencyValue}
import world.money.errors.ConversionError
val tenShillings = 10.KES
// A simple mock provider for the example
given mockProvider: ExchangeRateProvider with
def get(query: ConversionQuery): Either[ConversionError, ConversionRate] =
if (query.base == Currencies.KES && query.term == Currencies.JPY)
Right(ConversionRate(Currencies.KES, Currencies.JPY, BigDecimal("10.50")))
else
Left(ConversionError.RateNotFound(query))
// The target currency type is specified
val conversionResult = tenShillings.convertTo[Currencies.JPY.type]
conversionResult.foreach { jpyAmount =>
// The result is correctly typed as Money[Currencies.JPY.type]
assert(jpyAmount.value.unwrap == CurrencyValue(105.0).unwrap)
}
inline def divide(divisor: BigDecimal | Long | Int | Double)(using CurrencyMathContext): Either[ArithmeticError, Money[C]]
Extension method from Money

Attempts to divide this Money amount by a scalar value. Requires a given instance of world.money.currency.CurrencyMathContext.

Attempts to divide this Money amount by a scalar value. Requires a given instance of world.money.currency.CurrencyMathContext.

Attributes

Returns

An Either containing a errors.ArithmeticError on failure (e.g., division by zero), or the resulting Money instance.

Note

Using Double can lead to precision inaccuracies.

transparent inline def max(that: Money[C]): Money[C]
Extension method from Money

Returns the maximum of this amount and another.

Returns the maximum of this amount and another.

Value parameters

that

The other money amount to compare.

Attributes

Returns

The money amount with the larger value.

transparent inline def min(that: Money[C]): Money[C]
Extension method from Money

Returns the minimum of this amount and another.

Returns the minimum of this amount and another.

Value parameters

that

The other money amount to compare.

Attributes

Returns

The money amount with the smaller value.

transparent inline def multiply(multiplicand: BigDecimal | Long | Int | Double)(using CurrencyMathContext): Money[C]
Extension method from Money

Multiplies this Money amount by a scalar value. Requires a given instance of world.money.currency.CurrencyMathContext.

Multiplies this Money amount by a scalar value. Requires a given instance of world.money.currency.CurrencyMathContext.

Attributes

Note

Using Double can lead to precision inaccuracies.

transparent inline def rounded: Money[C]
Extension method from Money

Returns a Money instance with its value rounded to the currency's conventional number of fractional digits.

Returns a Money instance with its value rounded to the currency's conventional number of fractional digits.

This is useful for preparing a monetary amount for final representation or payment, adhering to the standard format of its currency.

Attributes

Returns

A new Money instance with the rounded value.

Note

This method uses RoundingMode.HALF_UP. For currencies without a defined minorUnit (e.g., precious metals like Gold), this operation has no effect and returns the instance unchanged.

Example
import world.money.*
val unrounded = 123.456.KES // KES has 2 minor units
val rounded = unrounded.rounded
// rounded is now 123.46.KES
val jpyAmount = 987.5.JPY // JPY has 0 minor units
val roundedJpy = jpyAmount.rounded
// roundedJpy is now 988.JPY
transparent inline def rounded(mode: RoundingMode): Money[C]
Extension method from Money

Returns a Money instance with its value rounded to the currency's conventional number of fractional digits, using a specified rounding mode.

Returns a Money instance with its value rounded to the currency's conventional number of fractional digits, using a specified rounding mode.

This method allows for explicit control over how rounding is performed, which is essential for financial applications that must comply with specific rounding rules.

Value parameters

mode

The RoundingMode to apply.

Attributes

Returns

A new Money instance with the rounded value.

Note

For currencies without a defined minorUnit (e.g., precious metals), this operation has no effect and returns the instance unchanged.

Example
import world.money.*
import scala.math.BigDecimal.RoundingMode
val amount = 123.456.KES
// Explicitly round down
val roundedDown = amount.rounded(RoundingMode.DOWN)
// roundedDown is now 123.45.KES
// Explicitly round up
val roundedUp = amount.rounded(RoundingMode.UP)
// roundedUp is now 123.46.KES
transparent inline def signum: Int
Extension method from Money

Returns the sign of this amount's value (-1, 0, or 1).

Returns the sign of this amount's value (-1, 0, or 1).

Attributes

transparent inline def subtract(subtrahend: Money[C] | CurrencyValue | BigDecimal | Long | Int | Double)(using CurrencyMathContext): Money[C]
Extension method from Money

Subtracts the value of subtrahend from this Money instance. Requires a given instance of world.money.currency.CurrencyMathContext.

Subtracts the value of subtrahend from this Money instance. Requires a given instance of world.money.currency.CurrencyMathContext.

Value parameters

subtrahend

The value to subtract.

Attributes

Returns

A new Money instance representing the difference.

Note

The value to be subtracted must either be another Money instance of the same currency, or a raw numeric type.

Using Double can lead to precision inaccuracies.

transparent inline def unary_-: Money[C]
Extension method from Money

Negates this Money amount.

Negates this Money amount.

Attributes

Example
 import world.money.*
-100.KES // Results in Money(-100, KES) 

Inherited methods

def productElementNames: Iterator[String]

Attributes

Inherited from:
Product
def productIterator: Iterator[Any]

Attributes

Inherited from:
Product

Concrete fields

val currency: C

The currency of this monetary amount.

The currency of this monetary amount.

Attributes