A type class separates an interface from the types that implement it. In Scala, a parameterized trait describes operations, while given instances adapt particular types to that interface. section 10.5
Folding through a Monoid
A generic foldMap needs only a Monoid[B], not a particular B implementation. The instance supplies combine and empty; the function maps each element and combines the results. With an Int-addition instance, folding List("abra", "ca", "dabra") over _.length produces a character count. section 10.5
Context parameters make the instance dependency explicit in the definition while allowing the compiler to locate a matching given at the call site. Supplying using manually selects another instance, such as Boolean conjunction or disjunction. section 10.5 section 10.9
def foldMap[A, B](as: List[A], m: Monoid[B])(f: A => B): B = #1
as.foldRight(m.empty)((a, acc) => m.combine(f(a), acc))
val intAddition: Monoid[Int] = new: #2
def combine(a1: Int, a2: Int) = a1 + a2
val empty = 0
val strings = List("abra", "ca", "dabra")
val charCount = foldMap(strings, intAddition)(_.length) #3
Trace the progression from an explicit Monoid argument to a context parameter and then to compiler-selected instances. section 10.5


