liveBook · Manning

Type-lifting function

As explained in Functional Programming in Scala, Second Edition

unit is a book-defined operation that constructs a state-threading computation containing a supplied value without changing the state.

A type-lifting function, conventionally named unit, takes an ordinary value and places it in a computation type. For state-threading computations, it constructs an action that returns the supplied value while passing its input state through unchanged: unit(a) is s => (a, s). The value becomes available to later composition without inventing a state transition. section 6.8

def unit[S, A](a: A): State[S, A] =
  s => (a, s)

The implementation makes the two obligations explicit: return a, and return the original s unchanged. section 6.8

This small operation supplies neutral starting values for larger computations. A state sequence begins with an action containing an empty list, then combines each action with that accumulator. Since the initial action does not consume or alter state, sequencing can build a result list while preserving the normal state flow of the real actions. section 6.8 section 11.7

Lifting a value into State

For State[Int, A], unit(List[(Int, A)]()) creates an action that initially yields an empty list and leaves the integer state intact. A fold can then use get and set to number elements, extending that lifted empty result one element at a time. section 11.5.2

The same name captures a broader pattern, but each computation type gives lifting its own meaning. Par.unit promotes a value to a parallel computation; Option uses Some; List creates a one-element list; Gen supplies a generated value. Unit therefore changes the surrounding computational context while retaining the supplied result. section 7.1.1 section 11.7

Unit supports derived combinators because it can introduce an ordinary value wherever a computation is required:

  • map can transform a computed result by flatMapping and lifting f(a) back into the same type. section 11.2.1
  • map2 and traverse use unit as the empty or neutral computation from which combined results are built. section 12.1 section 12.2
  • flatMap identity laws say that lifting before a continuation adds no observable extra computation, and lifting after one preserves it. section 11.4.3

In a Monad, unit and flatMap are chosen as a minimal primitive set. From them come map and map2, avoiding repeated implementations across Parser, Gen, Par, Option, and State. The Monad contract does not prescribe the hidden behavior of a computation; it requires associativity and identity laws, including the laws governing unit. section 11.2.1 section 11.7

Unit in parallel mapping

A Par value can be mapped without running it by pairing it with unit(()) and ignoring that placeholder in map2. This expresses sorting as a transformation inside Par rather than extracting a result, sorting it, and repackaging it. section 7.2.1 section 7.2.1

Applicative functors retain unit but pair it with map2 rather than flatMap. That supports context-free combination, traversal, and lifting functions into an effect, but cannot flatten F[F[A]] or make later computations depend on earlier results. Monad adds those context-sensitive capabilities through flatMap or join. section 12.2 section 12.3 section 12.9

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Defines state-preserving lifting, derives combinators from it, and states Monad and Applicative identity laws.
Examples
Uses empty-list state sequencing, element numbering, parallel sorting, and concrete Option, List, Par, and State instances.
What it assumes
Assumes Scala functions and generic types while developing functional computation types through concrete implementations.
What you can do after
Apply it via Monad or Applicative combinators to introduce values and construct composed computations.
How it connects
Connects State, Monad, Applicative, flatMap, map2, traverse, Par, Option, List, Gen, and join.

Also explained in

Compare how 4 books explain type-lifting function →

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.