We began this chapter by looking at what Haskell projects usually consist of and how Cabal and stack are used to manage project complexity and dependencies. We glanced at the basic usage of main test libraries and frameworks for Haskell and how they can be integrated into a cabalized project. We learned how to handle errors and exceptions. Even more importantly, we learned how to not do errors; why prefer throwIO
over error (or throw
)? Why are asynchronous errors so vicious in lazy semantics?
In the latter part of this chapter, we explored some Haskell trivia and techniques specific to GHC: lazy patterns, coding with GHC primitives (the magic hash), inlining, writing rewrite rules, using phantom types, fundeps, type families, the monomorphism restriction, and some useful GHC extensions. Now you should be able to both read and write cabal files, devise test suites with test libraries (QuickCheck, SmallCheck, and HUnit) and test frameworks (Hspec, Tasty), and throw
and catch
exceptions...