8 IO as Values

 

In this chapter you will learn how to

  • use values to represent side-effectful programs
  • use data from unsafe sources
  • safely store data outside your program
  • indicate your code does side effects
  • separate pure and impure code

...we have to keep it crisp, disentangled, and simple if we refuse to be crushed by the complexities of our own making...

— Edsger Dijkstra, “The next forty years”

8.1 Talking to the outside world

In this chapter we’ll finally address the elephant in the room.

Q          I now see how pure functions and trustworthy signatures can help me write better, more maintainable software. But let’s be honest. We will always need to get something from the outside: be it an API call or fetching things from a database. Additionally, almost every application in the world has a state that needs to be persisted somewhere. So isn’t this pure function concept "a bit" limited?

A          We can talk with the outside and still use pure function goodies! The intuition here is exactly the same as with error handling (chapter 6) and modeling requirements as types (chapter 7). We represent everything as values of descriptive types!

00_Qsmile

8.2      Integrating with an external API

8.3      Properties of a side-effectful IO action

8.4      Imperative solution to side-effecting IO code

8.5      Problems with the imperative approach to IO

8.6      Can we really do better using FP?

8.7      Doing IO vs using IO’s result

8.8      Handling IO imperatively

8.9      Computations as IO values

8.10  IO values

8.11  IO values in the wild

8.12  Pushing the impurity out

8.13  Using values fetched from two IO actions

8.14  Combining two IO values into a single IO value

8.15  Practicing creating and combining IO values

8.16  Disentangling concerns by working with values only

8.17  IO type is viral

8.18  Coffee Break: Working with values

8.19  Coffee Break Explained: Working with values

8.20  Towards functional IO

8.21  What about IO failures?

8.22  Running a program described by IO may fail!

8.23  Remember orElse?

8.24  Lazy and eager evaluation

8.25  Implementing recovery strategies using IO.orElse