liveBook · Manning

Tagless final interpreter

As explained in Functional Programming in Scala, Second Edition

A capability trait is an interface-based encoding of an effect algebra whose operations expose only the capabilities required by a program.

A tagless final interpreter encodes an effect algebra as a capability trait. Each operation returns a value in an abstract target monad, exposing only the capabilities a program requires. section 13.6

Unlike a free-monad program, the capability-trait approach does not first build an intermediate program and interpret it later. The target monad supplies sequencing directly, while instances provide concrete behavior. section 13.10 section 13.6

trait Console[F[_]]:
  def readLn: F[Option[String]]
  def printLn(line: String): F[Unit]

A Console capability exposes reading and printing without committing programs to a particular effect implementation. section 13.6

The pattern separates three responsibilities:

  • Declare primitive operations as methods on a capability trait parameterized by F. section 13.6
  • Implement the trait for each target monad, such as Par or Function0. section 13.6
  • Write polymorphic programs whose required capabilities and Monad instance appear in their context. section 13.6

Greeting with Console

A polymorphic greet program prints a question, reads a name, and prints either a personalized greeting or a fallback. The same program can run with different Console and target-monad instances. section 13.6

Combining capabilities

A cat program requires Console, Files, and Monad capabilities, reads file lines, and prints them without granting unrelated database or network access. section 13.6

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Defines traits, implementations, sequencing, and polymorphic programs, but stops short of detailing every concrete interpreter.
Examples
Uses Console, Files, greet, cat, Par, Function0, and a general-purpose IO type.
What it assumes
Assumes monads and algebraic data types while teaching capability traits through concrete I/O programs.
What you can do after
Build effectful programs polymorphically and run them through capability instances for selected target monads.
How it connects
Connects capability traits to free monads, monads, IO, algebraic data types, and the principle of least power.

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.