liveBook · Manning

Flatmap constructor

As explained in Functional Programming in Scala, Second Edition

The FlatMap constructor represents continuation of an IO computation by applying a function to the result of a preceding computation.

The FlatMap constructor represents continuing an IO computation with the result of an earlier computation. It stores a subcomputation and a continuation function, rather than executing either immediately. section 13.3.1

The flatMap method constructs FlatMap(this, f) and returns at once. Later, the interpreter evaluates the subcomputation, passes its result to the continuation, and continues interpreting the returned IO value. Pattern matching on nested constructors preserves tail recursion instead of nesting unsafeRun calls. section 13.3.1

Repeated output

A printLine action can be repeated with printLine("Still going...").forever. This produces a nested FlatMap structure whose continuation schedules the next action; the interpreter traverses that structure and performs each effect. section 13.3.1

Listing 13.4 Creating a new IO type
enum IO[A]:
  case Return(a: A)                             #1
  case Suspend(resume: () => A)                 #2
  case FlatMap[A, B](
    sub: IO[A], k: A => IO[B]) extends IO[B]    #3
 
  def flatMap[B](f: A => IO[B]): IO[B] =
    FlatMap(this, f)
  def map[B](f: A => B): IO[B] =
    flatMap(a => Return(f(a)))

Inspect the IO definition: FlatMap stores sub: IO[A] and k: A => IO[B], while flatMap creates the constructor directly. section 13.3.1

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Explains stored continuations, delayed execution, nested structures, and tail-recursive interpretation.
Examples
Uses printLine, forever, nested FlatMap structures, and a pattern-matching unsafeRun interpreter.
What you can do after
Build it from scratch by representing flatMap as a constructor and interpreting its continuation without losing tail recursion.
How it connects
Connects IO with flatMap, interpreters, Return, Suspend, and tail recursion.

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.