Skip to content

Introduction

This book gives you an introduction to functional programming in Haskell. You may choose not to follow this book for learning Haskell. Two excellent introductions to Haskell that may appeal more to you or may supplement your reading are:

  • Learn You a Haskell for Great Good. I've never used it myself, but it is very popular among newcomers to Haskell.

  • Real World Haskell. This is a book that I used to own in printed form until I gave it to one of my students. It is an excellent book, written by a mix of academics and practitioners who use Haskell for non-trivial programming in the real world.

Both books can be bought or read for free online. However, there are two advantages to using this online book:

  • It is explicitly designed for you to work through on your computer, so you can gain hands-on experience.

  • I've placed some focus on implementing interesting algorithms in Haskell. Most introductory programming books explain how to accomplish practically important but ultimately mundane tasks of shovelling data from point A to point B. These descriptions often do not talk about how to implement interesting algorithms effectively and elegantly in these programming languages, and it isn't always easy to see how to do this based on the discussion of much simpler examples. You will only truly understand how to use a programming language if you try to do non-trivial stuff with it. It helps you get a better understanding of the types of programming patterns that are easy or hard to express in the language. I will still use simple examples to introduce the different features of Haskell, but whenever we have learned enough to do something more interesting, I will present a bigger algorithm that pulls what we have learned together.

  • Many books that introduce you to programming in Haskell, such as the ones above, try to be pragmatic by just getting to work and getting you to program in Haskell. They seem to approach the topic from the angle that Haskell is just another programming language and once you understand its syntax and how it works, you are good to go. As such, they are right, of course. However, if you know Java and want to learn Python, Rust or C++, then your biggest challenge is to learn the syntax of these languages and the idioms—the most elegant and commonly used techniques for implementing common programming patterns in these languages. The underlying principles of all of these languages, on the other hand, are exactly the same—they are all imperative languages.

    Haskell is a functional language, and functional programming is very different from imperative programming. Learning how to become an effective functional programmer requires more than mapping your familiar programming patterns onto the syntax of a new language. You need to learn to think differently about what a computation is. Doing this will increase your understanding of programming in general and is one of the reasons why you are expected to learn how to program functionally in this course, but it requires a more careful approach to learning this language.

    I start very slowly, by explaining the fundamental difference between functional programming and imperative programming. As I just said, when programming functionally or imperatively, our concept of what a program even is is very different. At the end of this term, you will have to judge whether I succeeded in making you understand this difference and whether it helped you, but I felt that it was worth to try another tack. I've seen many students struggle with programming in Haskell in the past, and it seemed obvious to me that their difficulties almost always resulted from them trying to program imperatively in Haskell, which is not just hard but simply impossible. The downside of this different approach is that we will stay in a purely functional world for a long time, a world where we cannot read files or print to the screen—we won't be able to write complete executables for a long time. To do that, we need to understand monads, a topic I cover only towards the end of this book.

    Since I couldn't avoid mentioning monads, let me add a preemptive comment here. You may have heard about monads before, and that they are one of the hardest things to wrap your head around in Haskell. That's true only if you approach them pragmatically, by trying to use them without understanding what a simple concept a monad really is. The reason why I leave them to the end of the book is not because I want to postpone talking about difficult stuff but because I feel that you need to be comfortable with plain old pure functions first before you will appreciate that monads are simply a way to look at computations with side effects through a functional lens.