This book is devoted to five main principles of algorithm design: divide
and conquer, greedy algorithms, thinning, dynamic programming, and
exhaustive search. These principles are presented using Haskell, a
purely functional language, leading to simpler explanations and shorter
programs than would be obtained with imperative languages. Carefully
selected examples, both new and standard, reveal the commonalities and
highlight the differences between algorithms. The algorithm developments
use equational reasoning where applicable, clarifying the applicability
conditions and correctness arguments. Every chapter concludes with
exercises (nearly 300 in total), each with complete answers, allowing
the reader to consolidate their understanding and apply the techniques
to a range of problems. The book serves students (both undergraduate and
postgraduate), researchers, teachers, and professionals who want to know
more about what goes into a good algorithm and how such algorithms can
be expressed in purely functional terms.