Mutable Data in the Real World

Mutable Data in the Real World

IO actions give us a way to represent computations that interact with the real-world. One of the important ways that we can interact with the real world that we haven’t yet looked at is how to read and write real-world state. In this chapter you’ll learn how to deal with persistent mutable values in the real world using IO references.

In this chapter you’ll learn how to build programs that interact with real-world data that can change over time as your program runs. You’ll also learn more about how Haskell programs run.

After you’ve finished this chapter you’ll know how to write functions that have persistent data that you can update over time.

Mutable data can be useful for building metrics and logging systems, writing certain efficient algorithms, and for debugging and testing your code. These things will all be important as you start building larger and more sophisticated programs.

traverseDirectoryIO

Write a new function, traverseDirectoryIO that has the type:

traverseDirectoryIO :: FilePath -> (FilePath -> IO a) -> IO [a]

This function should behave like traverseDirectory' but should accept a function returning an IO action, rather than a value.

Hint 1

Some high level hint text

Hint 2

Some more detailed hint text

Hint 3

Even more detailed hint text

Solution

A complete solution for the exercise

Timing Pure Functions

The timeFunction that you built as you worked through this chapter only supports timing IO actions. Try writing a version of this function that also works for pure values, with the type:

timePureFunction :: Metrics -> String -> a -> IO a

What are the limitations to your implementation function? Are there things that a user of the function could do to ensure that the timing information was better?

Hint 1

Some high level hint text

Hint 2

Some more detailed hint text

Hint 3

Even more detailed hint text

Solution

A complete solution for the exercise

Metrics Strictness

Consider the MetricsStore type that you defined earlier in this chapter:

data MetricsStore = MetricsStore
  { successCount :: Int
  , failureCount :: Int
  , callDuration :: Map.Map String Int
  } deriving (Eq, Show)

How might you make use of strictness to improve the performance of metrics? Try writing some metrics collecting functions using several different approaches to strictness and profiling the results.

Hint 1

Some high level hint text

Hint 2

Some more detailed hint text

Hint 3

Even more detailed hint text

Solution

A complete solution for the exercise