liveBook · Manning

Sequence

As explained in Functional Programming in Scala, Second Edition

sequence combines nested effectful values by exchanging the order of their outer and inner type constructors when the inner context is applicative.

`sequence` turns a list of effectful values inside out. For `List[Option[A]]`, it produces `Option[List[A]]`: all `Some` values become one `Some` list, while any `None` makes the whole result `None`. This lets a collection retain the failure behavior of each element rather than extracting values unsafely. section 4.3.2

A common need is parsing many strings with a function that may fail. Mapping `toIntOption` first yields `List[Option[Int]]`; sequencing that list yields either every parsed integer or failure. Doing map followed by sequence traverses the list twice, motivating `traverse`, which combines mapping and sequencing in one pass. section 4.3.2

def sequence[A](as: List[Option[A]]): Option[List[A]] =
  as.foldRight[Option[List[A]]](Some(Nil))((a, acc) => map2(a, acc)(_ :: _))

The implementation folds from the right, beginning with a successful empty list. Each option is combined with the accumulated option-list through `map2` and list cons, so failure propagates automatically. section 4.6

The same assembly pattern reappears wherever a list contains computations rather than plain values:

  • For random-number actions, sequence threads the RNG through each action and collects the generated values. section 6.8
  • For state actions, sequence runs each transition in order and returns the collected results with the final state. section 6.8
  • For `Either`, sequence returns the first encountered error instead of a list of successful values. section 4.4

From sequence to traverse

Once `traverse(as)(f)` is available, `sequence` needs no separate traversal logic: each list element is already an `Option`, so traverse receives the identity function. This exposes sequence as the special case of traversing with no additional transformation. section 4.6

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Derives a foldRight implementation with map2, then rewrites sequence through traverse.
Examples
Uses string-to-integer parsing, random-number actions, and state-machine input processing.
What it assumes
Assumes Option, map2, lists, and foldRight while introducing sequence as an exercise.
What you can do after
Build it from scratch with foldRight and map2, or define it through traverse.
How it connects
Connects Option, Either, Rand, State, map2, foldRight, and traverse.

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.