Thinking Functionally with Haskell

THINKING FUNCTIONALLY WITH HASKELL

Richard Bird is famed for the clarity and rigour of his writing. His new textbook, which introduces functional programming to students, emphasises fundamental techniques for reasoning mathematically about functional programs. By studying the underlying equational laws, the book enables students to apply calculational reasoning to their programs, both to understand their properties and to make them more efficient.

The book has been designed to fit a first-or second-year undergraduate course and is a thorough overhaul and replacement of his earlier textbooks. It features case studies in Sudoku and pretty-printing, and over 100 carefully selected exercises with solutions. This engaging text will be welcomed by students and teachers alike.

THINKING FUNCTIONALLY WITH HASKELL

RICHARD BIRD

University of Oxford

University Printing House, Cambridge CB2 8BS, United Kingdom Cambridge University Press is part of the University of Cambridge.

It furthers the University’s mission by disseminating knowledge in the pursuit of education, learning and research at the highest international levels of excellence.

www.cambridge.org
Information on this title:
www.cambridge.org/9781107087200

© Richard Bird 2015

This publication is in copyright. Subject to statutory exception and to the provisions of relevant collective licensing agreements, no reproduction of any part may take place without the written permission of Cambridge University Press.

First published 2015

Printed in the United Kingdom by CPI Group Ltd, Croydon CR0 4YY

A catalogue record for this publication is available from the British Library
Library of Congress Cataloguing in Publication data

Bird, Richard, 1943-
Thinking functionally with Haskell / Richard Bird, University of Oxford.
pages cm
ISBN 978-1-10708720-0 (hardback) – ISBN 978-1-107-45264-0 (paperback)
1. Functional programming (Computer science) I. Title.
QA76.62.B573 2014
005.1′14–dc23
2014024954

ISBN 978-1-10708720-0 Hardback
ISBN 978-1-107-45264-0 Paperback Additional resources for this publication at
www.cambridge.org/9781107087200

Cambridge University Press has no responsibility for the persistence or accuracy of URLs for external or third-party internet websites referred to in this publication, and does not guarantee that any content on such websites is, or will remain, accurate or appropriate.

Contents

Preface

1 What is functional programming?

1.1 Functions and types

1.2 Functional composition

1.3 Example: common words

1.4 Example: numbers into words

1.5 The Haskell Platform

1.6 Exercises

1.7 Answers

1.8 Chapter notes

2 Expressions, types and values

2.1 A session with GHCi

2.2 Names and operators

2.3 Evaluation

2.4 Types and type classes

2.5 Printing values

2.6 Modules

2.7 Haskell layout

2.8 Exercises

2.9 Answers

2.10 Chapter notes

3 Numbers

3.1 The type class
Num

3.2 Other numeric type classes

3.3 Computing floors

3.4 Natural numbers

3.5 Exercises

3.6 Answers

3.7 Chapter notes

4 Lists

4.1 List notation

4.2 Enumerations

4.3 List comprehensions

4.4 Some basic operations

4.5 Concatenation

4.6
concat
,
map
and
filter

4.7
zip
and
zipWith

4.8 Common words, completed

4.9 Exercises

4.10 Answers

4.11 Chapter notes

5 A simple Sudoku solver

5.1 Specification

5.2 Lawful program construction

5.3 Pruning the matrix of choices

5.4 Expanding a single cell

5.5 Exercises

5.6 Answers

5.7 Chapter notes

6 Proofs

6.1 Induction over natural numbers

6.2 Induction over lists

6.3 The function
foldr

6.4 The function
foldl

6.5 The function
scanl

6.6 The maximum segment sum

6.7 Exercises

6.8 Answers

6.9 Chapter notes

7 Efficiency

7.1 Lazy evaluation

7.2 Controlling space

7.3 Controlling time

7.4 Analysing time

7.5 Accumulating parameters

7.6 Tupling

7.7 Sorting

7.8 Exercises

7.9 Answers

7.10 Chapter notes

8 Pretty-printing

8.1 Setting the scene

8.2 Documents

8.3 A direct implementation

8.4 Examples

8.5 The best layout

8.6 A term representation

8.7 Exercises

8.8 Answers

8.9 Chapter notes

9 Infinite lists

9.1 Review

9.2 Cyclic lists

9.3 Infinite lists as limits

9.4 Paper–rock–scissors

9.5 Stream-based interaction

9.6 Doubly-linked lists

9.7 Exercises

9.8 Answers

9.9 Chapter notes

10 Imperative functional programming

10.1 The
IO
monad

10.2 More monads

10.3 The
State
monad

10.4 The
ST
monad

10.5 Mutable arrays

10.6 Immutable arrays

10.7 Exercises

10.8 Answers

10.9 Chapter notes

11 Parsing

11.1 Parsers as monads

11.2 Basic parsers

11.3 Choice and repetition

11.4 Grammars and expressions

11.5 Showing expressions

11.6 Exercises

11.7 Answers

11.8 Chapter notes

12 A simple equational calculator

12.1 Basic considerations

12.2 Expressions

12.3 Laws

12.4 Calculations

12.5 Rewrites

12.6 Matchings

12.7 Substitutions

12.8 Testing the calculator

12.9 Exercises

12.10 Answers

12.11 Chapter notes

Index

Preface

The present book is a completely rewritten version of the second edition of my
Introduction to Functional Programming using Haskell
(Prentice Hall). The main changes are: a reorganisation of some introductory material to reflect the needs of a one or two term lecture course; a fresh set of case studies; and a collection of over 100 exercises that now actually contain answers. As before, no knowledge of computers or programming is assumed, so the material is suitable as a first course in computing.

Every author has his or her own drum to beat when writing a textbook, and the present one is no different. While there are now numerous books, tutorials, articles and blogs devoted to Haskell, few of them emphasise what seems to me the main reason why functional programming is the best thing since sliced bread: the ability to think mathematically about functional programs. And the mathematics involved is neither new nor difficult. Any student who has come to grips with, say, high-school trigonometry and has applied simple trigonometric laws and identities to simplify expressions involving sines and cosines (a typical example: express sin 3
α
in terms of sin
α
) will quickly appreciate that a similar activity is being proposed for programming problems. And the payoff is there at the terminal: faster computations. Even after 30 years I still get a great deal of pleasure from writing down a simple, obvious, but inefficient way to solve a problem, applying some well-known equational laws, and coming up with another solution that is ten times faster. Well, if I’m lucky.

If the message of the last paragraph turns you off, if you are perpetually running away from the Mordor of Mathematics, then the present book is probably not for you. Probably, but not necessarily so (nobody likes to lose customers). There is still pleasure to be gained in learning a novel and exciting way to write programs. Even programmers who for one reason or another do not or cannot use Haskell
in their daily work, and certainly do not have the time to spend calculating better answers to their problems, have still been inspired by the enjoyment of learning Haskell and are hugely appreciative of its ability to express computational ideas and methods simply and briefly. In fact, the ability to express programming ideas in a purely functional style has been slowly incorporated into mainstream imperative programming languages, such as Python, Visual Basic, and C#.

One final but important point: Haskell is a large language and this book by no means covers all of it. It is not a reference guide to Haskell. Although details of the language appear on almost every page, especially in the earlier chapters, my primary intention is to convey the essence of functional programming, the idea of thinking functionally about programs, not to dwell too much on the particulars of one specific language. But over the years Haskell has absorbed and codified most of the ideas of functional programming expressed in earlier functional languages, such as SASL, KRC, Miranda, Orwell and Gofer, and it is difficult to resist the temptation to explain everything in terms of this one super-cool language.

Most of the programs recorded in this book can be found on the website
www.cs.ox.ac.uk/publications/books/functional

It is hoped to add more exercises (and answers), suggestions for projects, and so on, in due course. For more information about Haskell, the site
www.haskell.org
should be your first port of call.

Acknowledgements

The present book arose out of lecture notes I prepared based on the second edition. It has benefited enormously from the comments and suggestions by tutors and students. Others have emailed me with constructive comments and criticisms, or simply to point out typos and silly mistakes. These include: Nils Andersen, Ani Calinescu, Franklin Chen, Sharon Curtis, Martin Filby, Simon Finn, Jeroen Fokker, Maarten Fokkinga, Jeremy Gibbons, Robert Giegerich, Kevin Hammond, Ralf Hinze, Gerard Huet, Michael Hinchey, Tony Hoare, Iain Houston, John Hughes, Graham Hutton, Cezar Ionescu, Stephen Jarvis, Geraint Jones, Mark Jones, John Launchbury, Paul Licameli, David Lester, Iain MacCullum, Ursula Martin, Lambert Meertens, Erik Meijer, Quentin Miller, Oege de Moor, Chris Okasaki, Oskar Permvall, Simon Peyton Jones, Mark Ramaer, Hamilton Richards, Dan Russell, Don Sannella, Antony Simmons, Deepak D’Souza, John Spanondakis, Mike Spivey, Joe Stoy, Bernard Sufrin, Masato Takeichi, Peter Thiemann, David Turner, Colin Watson, and Stephen Wilson. In particular, Jeremy Gibbons, Bernard Sufrin
and José Pedro Magalhǎes have read drafts of the manuscript and suggested a number of corrections.

Other books

Jagged Edge by Mercy Cortez
Haunting of Lily Frost by Weetman, Nova
Lovely, Dark, and Deep by Julia Buckley
Cowboy of Mine by Red L. Jameson
Dark Refuge by Kate Douglas