An identity law says that a designated neutral value leaves another value unchanged when combined with it. For a monoid, `empty` must work on either side: combining `empty` with `a`, or `a` with `empty`, yields `a`. This requirement is practical: it makes an empty input a safe starting value for folds and combinations. section 10.9
val intAddition: Monoid[Int] = new: def combine(x: Int, y: Int) = x + y val empty = 0 val intMultiplication: Monoid[Int] = new: def combine(x: Int, y: Int) = x * y val empty = 1 val booleanOr: Monoid[Boolean] = new: def combine(x: Boolean, y: Boolean) = x || y val empty = false val booleanAnd: Monoid[Boolean] = new: def combine(x: Boolean, y: Boolean) = x && y val empty = true
These monoids make the neutral value concrete: zero for addition, one for multiplication, false for disjunction, and true for conjunction. section 10.9
Choosing an identity for Option
For `Option[A]`, no general `A` value can be constructed, so `None` is the viable `empty`. The identity law then rules out returning `None` when combining it with `Some(x)`: `combine(empty, Some(x))` must remain `Some(x)`. A first-option monoid therefore uses `None` as empty and returns the first present value. section 10.9
The same idea appears at other abstraction levels. A functor preserves identity when mapping the identity function changes nothing: `x.map(a => a) == x`. A monad uses `unit` as the identity for composition: composing a function with `unit` on either side leaves that function unchanged. section 11.1.1 section 11.4.3
compose(f, unit) == f #1 compose(unit, f) == f #2
These two equations state monadic right and left identity directly in terms of composition. section 11.4.3
Identity laws are useful because they constrain implementations without prescribing their internal behavior. Together with associativity, they let generic operations rely on predictable composition; a lawful Monad instance gains derived combinators after implementing a minimal set of operations. section 11.7
