15 Transformers for synchronizing

 

This chapter covers

  • Using monad transformers to extend the abilities of monads
  • Structuring an application using a monad-transformer stack with a read-only environment, an event log, and state
  • Providing the application with command-line arguments, using the optparse-applicative package

In the last chapter, we began building an application to synchronize directory structures. We have also dealt with reading and writing files as well as handling exceptions. Now, we want to use this functionality to build the application.

To structure our program, we want to use monad transformers to more easily construct effectful computations that have access to read-only data, modify state, and collect output instead of simply relying on the IO monad. We also provide command-line arguments, using the optparse-applicative package.

15.1 Monad transformers

Let’s first define what features our file synchronization application should have. In general, the user can specify one source and one destination path but also needs to be able to limit the type of files being copied. Additionally, the user should be able to limit the synchronization to a certain recursive directory depth and an upper bound to the number of files that should be copied. While the synchronization is in progress, we will have to manage some state that will be used to check against the limits set by the user, which includes the recursion depth and the number of already transferred files.

15.1.1 Reading an environment with ReaderT

15.1.2 StateT and WriterT

15.1.3 Stacking multiple transformers with RWST

15.2 Implementing an application

15.3 Providing a CLI

15.3.1 Parsing arguments with optparse-applicative

15.3.2 Enumerating custom types

15.3.3 The Enum class

15.3.4 A CLI for App

Summary