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
