Now that we’ve completed our meandering journey through the realm of functional library design, we should be equipped to deal with most design problems that might cross our path. Along the way, we’ve picked up some new skills, such as applying the design principles of compositionality and algebraic reasoning.
Part 3 takes a few steps back to look at the bigger picture. As we’ve progressed through the first two parts by establishing building blocks (part 1) and using them in our own designs (part 2), we’ve seen some common patterns emerging. This part of the book identifies these commonalities and turns them into abstractions or patterns that can be reused and applied wherever needed. The primary goal is to train you to recognize such patterns when designing your own libraries and to write code that takes full advantage of extracting them.
These abstractions should not be confused with polymorphic hierarchies, which we have come to know in object-oriented design. Here the abstractions are more conceptual and provide functionality that is decoupled from the classes they enhance—although, just like in object orientation, the end goal is to eliminate unnecessary duplication in our code.