Why do we like Haskell? It provides a combination of abstraction and concreteness that let us address a wide range of problem sizes. When we have small problems to solve, we write short programs that would normally be considered the domain of “scripting” languages, because Haskell is expressive and has good standard libraries. When we need to write larger and more demanding applications, Haskell's robustness and composability help us to build maintainable code that we can adapt quickly to changes in circumstance.
In every chapter, we've interlaced the material with exercises. We think that taking the time to solve them is a great idea, one that will pay you back hugely. Don't just think about how you would solve an exercise; sit in front of a computer and write working code!
With exploration comes the risk of occasionally getting lost. We'll be trying to anticipate your questions as we go, but maybe once in a while we'll take a step a little too quickly. Any time you feel like you're not quite getting it yet, relax. Pretty often your best approach will be to try a few coding exercises, to explore a topic where we didn't make things clear enough. Nothing will help you learn better than practice and a willingness to try a few different ways around an obstacle.
We have a few important non-goals in writing this book. The first is that we're not triumphalists; when we say nice things about functional programming, we're not implicitly saying bad things about someone else's cherished way of getting things done.
We will not sugar-coat problem topics. No language is perfect; neither is any language's standard library. When we cover aspects of the language or libraries that are less than perfect, we'll be clear about what the limitations are.