This chapter continues from what we’ve learned so far about monads and algebraic data types and extends them to handle external effects like interacting with databases or the console, or reading and writing to files. We develop a monad called IO with the specific purpose of dealing with such I/O effects in a purely functional way.
We’ll make an essential distinction in this chapter between effects and side effects. The IO monad provides a straightforward way of embedding imperative programming with I/O side effects in a pure program, all while preserving referential transparency. Doing so clearly separates effectful code that has an effect on the outside world from the rest of our program.
This will also illustrate an essential technique for dealing with external effects. We will use pure functions to compute a description of an effectful computation, which is then executed by a separate interpreter that actually performs those effects. Essentially, we’re crafting an embedded domain-specific language (EDSL) for imperative programming. This is a powerful technique that we’ll use throughout the rest of part 4. Our goal is to equip you with the skills needed to craft your own EDSLs for describing such effectful programs.