A first-class value can be stored, returned, passed to functions, and manipulated like other values. Making Charge first-class separates coffee purchases from payment processing, improving reuse and testability. section 1.1.2
First-class values enable several useful designs:
- Return a purchase together with its Charge instead of performing payment effects immediately. section 1.1.2
- Reuse buyCoffee to implement repeated purchases and combine their charges. section 1.1.2
- Pass functions to groupBy, map, and reduce to organize and combine charges by card. section 1.1.2
Coalescing charges
def coalesce(charges: List[Charge]): List[Charge] = charges.groupBy(_.cc).values.map(_.reduce(_.combine(_))).toList This groups charges by credit card and combines each group into one reusable, testable value. section 1.1.2
case class Charge(cc: CreditCard, amount: Double): #1
def combine(other: Charge): Charge =
if cc == other.cc then #2
Charge(cc, amount + other.amount) #3
else
throw Exception("Can't combine charges with different cards") #4
Inspect how Charge is represented as a value with an operation for combining compatible charges. section 1.1.2






