The material is grouped into three parts. In the first, we build a foundation, focusing on programming over basic types and lists, using first-order, non-polymorphic programs. Only when readers are fluent with the basics of functions, types and program construction do we look at the twin ideas of higher-order functions and polymorphism, which together give modern functional programming its distinctive flavour and power. Based on this, in the final part we look at larger-scale programming, supported also by an exploration of user-defined types, modules and lazy evaluation, and concluding with an analysis of program efficiency.
As we saw above, we can write down calculations of expressions which use our defined functions, and also give proofs of various of their properties; both aspects are emphasised in the text (although it can be read independently of the material on proof).
The crucial test of any programming text is whether it helps the reader to write programs. The book is called `The Craft of Functional Programming' because it aims to give readers help with design of programs right from the start. At each stage we give advice on how functions, types or modules can be designed; in many cases we give a series of steps which aim to simplify the problem by breaking it down into simpler parts.
Software of any importance will be modified during its lifetime; modification and re-use are emphasised when we discuss design, and in the final part of the book we look in particular at how libraries of polymorphic higher-order functions can be re-used in many different contexts.
The advice on design is supplemented by examples and case studies of varying size and complexity. Some, like the Huffman coding example, are free-standing; others, such as the library database, are re-visited a number of times to illustrate how new techniques can be applied to solve existing problems in different ways. This is important in linking together the different parts of the text, and in showing the variety of ways that any problem can be solved in Miranda.
Finally, other case studies are introduced step-by-step. We first see the simulation example when we design algebraic data types in Chapter 9; next it provides realistic examples of abstract data types in Chapter 11, and finally we look at its top level in Chapter 13. Each aspect is separate; together they provide a substantial case study. Other aspects of our approach are