13 External effects and I/O

 

This chapter covers

  • Segregating pure functions from effects in a program
  • Separating effectful concerns using an I/O data type
  • Hiding effectful code in data type abstractions
  • Implementing a free monad for flexible I/O delegation

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.

13.1 Factoring effects out of an effectful program

13.2 Introducing the IO type to separate effectful code

13.2.1 Handling input effects

13.2.2 Benefits and drawbacks of the simple IO type

13.3 Avoiding stack overflow errors by reification and trampolining

13.3.1 Reifying control flow as data constructors

13.3.2 Trampolining: A general solution to stack overflow

13.4 A more nuanced IO type

13.4.1 Reasonably priced monads

13.4.2 A monad that supports only console I/O

13.4.3 Testing console I/O by using pure interpreters

Summary