liveBook · Manning

Associativity

As explained in Functional Programming in Scala, Second Edition

The algebraic law stating that regrouping repeated applications of a binary operation does not change the result.

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

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Defines the law algebraically, tests it with generated triples, and applies it to folds, monads, and applicatives.
Examples
Uses strings, integers, Booleans, lists, generated law tests, function composition, and nested effect pairs.
What it assumes
Introduces associativity through concrete Scala operations before relying on abstract algebraic interfaces.
What you can do after
Evaluate/understand whether regrouping preserves a computation and why associative operations enable reusable folds.
How it connects
Connects monoids, identity, foldMap, parallelism, monads, flatMap, applicatives, map3, and product.

Also explained in

Compare how 5 books explain associativity →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Programming in Scala, Second Edition. The section links point to the parts of the book it draws on.