liveBook · Manning

Identity law

As explained in Functional Programming in Scala, Second Edition

A left identity law states that combining the identity with an operation on its left leaves the operation unchanged.

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

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Derives an Option monoid identity, then states functor and monad identity equations without proving their equivalence.
Examples
Uses addition, multiplication, Boolean operations, `Option`, and identity-function mapping as law instances.
What it assumes
Introduces identity through concrete Scala operations while relying on familiarity with `Option`, functions, and `map`.
What you can do after
Evaluate/understand whether neutral values and monadic `unit` preserve values under combination or composition.
How it connects
Connects monoids, `Option`, functors, `map`, monads, `unit`, `flatMap`, `compose`, and 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.