In this chapter, we’ll take what we’ve learned so far about monads and algebraic data types and extend it to handling external effects, like reading from databases and writing to files. We’ll develop a monad for I/O, aptly called IO, that will allow us to handle such external effects in a purely functional way.
We’ll make an important distinction in this chapter between effects and side effects. The IO monad provides a straightforward way of embedding imperative programming with I/O effects in a pure program, while preserving referential transparency. It clearly separates effectful code─code that needs to have some effect on the outside world─from the rest of our program.
This will also illustrate a key technique for dealing with external effects: using 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 we’ll use throughout the rest of part 4. Our goal is equipping you with the skills needed to craft your own EDSLs for describing effectful programs.