Associativity says that regrouping repeated uses of a binary operation does not change the result: combine(combine(x, y), z) == combine(x, combine(y, z)). It does not say that operands may be reordered; it only permits moving parentheses. String concatenation, integer addition and multiplication, and Boolean && and || all satisfy the law. section 10.1
A law behind one interface
A Monoid[A] supplies combine and empty. Associativity makes a sequence of combines unambiguous despite its grouping, while empty supplies a neutral starting value. For strings, combine is + and empty is ""; for lists, combine is ++ and empty is Nil. section 10.1
trait Monoid[A]: def combine(a1: A, a2: A): A #1 def empty: A #2
The minimal Monoid interface separates the operations from the laws they must obey. An implementation is useful only when its combine operation is associative and empty is an identity. section 10.1
The law can be tested rather than assumed. Generate three values a, b, and c, then compare the left- and right-associated combinations. Testing identity separately helps identify whether a failing implementation violates grouping or neutrality. section 10.9
Associativity has a practical payoff: folds may combine portions of a structure in different tree shapes and still agree. That permits divide-and-conquer folding and parallel combination when the surrounding operation supports it. section 10.9 section 10.8
The same reasoning reappears beyond monoids. Monad associativity requires chained flatMap calls to agree with nesting the later computation inside the first. Applicative associativity requires differently grouped product operations to agree after reshaping nested pairs; otherwise separate left- and right-grouped combinators would proliferate. section 11.7 section 12.5.2




