I'm not sure the author's explained this point quite as clearly as it could have been. One doesn't want to expose every type used in the program across all modules: there are many that are just used in internal representations within particular modules.
Here's an example from a project of mine, which is a command line program to produce truth tables. There's a Core module which contains the types shared across the whole program, and the most fundamental operations on them.
https://github.com/beastaugh/hatt/blob/1.5.0.3/src/Data/Logi...
Then there are other modules like Parser which just exposes a single function, but of course makes use of the core types.
https://github.com/beastaugh/hatt/blob/1.5.0.3/src/Data/Logi...
The command line program itself is defined as a Main module, which imports the pure library modules and does all the I/O. It has a few types of its own but these aren't shared across the program, because the library doesn't need to know about all this stuff.