People ask me a lot how they can best get started with programming, functional programming, or Haskell specifically. I think Haskell Programming from First Principles, which was written for beginners, is a great place to start, but FULL DISCLOSURE, I am one of its authors. I’m going to try to collect here the things that I have personally found most helpful for getting started with programming and with Haskell. It’s an opinionated collection. It might not be perfectly suited to your needs, but these are things that worked for me.
What to do first
OK, you’re here looking at a Haskell-ish blog already so maybe you don’t need this advice. But. Just in case.
This Getting Started guide will help you get set up quickly.
If you are not already a Nix user, I recommend you use Stack and look through some of its documentation. The documentation for it is fairly thorough.
If you are itching to write some Haskell, try Writing Simple Haskell.
When we’re talking about learning resources, I am very opinionated. In the course of writing our Haskell book, I have read most of the other Haskell books. I recognize that not everyone’s judgments here will be the same as mine, but these are what worked best for me (totally new programmer with not a lot of math background):
- Haskell Wikibook: The wikibook is free, which is awesome, and it really starts from the basics and works its way up in a nice progression. It has some exercises, although you’ll want more. You can get more exercises by doing cis194, the 99 Haskell Problems, and the NICTA course, among other things. All of those are free. The wikibook does have uneven coverage – some topics aren’t covered enough and some parts are not as well written as others, which just follows from it being a wikibook. However, I found many parts of it very clear and reasonably easy to follow.
Haskell Programming from First Principles by Chris Allen and Julie Moronuki: Sure. It’s my book. This is how I learned Haskell, so it covers thoroughly all the things I didn’t know, which was everything. It assumes no particular background knowledge besides some familiarity with high school level algebra. It goes from the lambda calculus through monad transformers, parser combinators, and exception handling, so it covers more than enough to get you working on your own projects in Haskell (or other functional languages). It has quite a few exercises.
Haskell: The Craft of Functional Programming by Simon Thompson: Ah, this book is not free, and it’s not perfect, but I do love this book. It has quite a few exercises, and I found them interesting and challenging without making me want to hurl the book through the window.
There is also what used to be known as “the NICTA course”. This is a great course, challenging but well structured. My best recommendation for most people is either to work through it with a mentor who knows Haskell or to work through it while reading or working through supplementary material.
For those who prefer video or blog post learning that still has structure like a book, rather than being a random collection of stuff, Type Classes has projects and courses for beginner, intermediate, and advanced Haskell.
No Monads for You
A lot of people who have experience programming in other languages think the big thing they need to learn about Haskell is monads and try to start there. So, here are my suggestions for beginning monads:
If you really can’t wait, try this post.
Blog Posts and Tutorials
Good, good, now that you’ve decided to forego learning about monads until you have a better understanding of types, typeclasses, functors and all that, here are some blog posts and tutorials from around the web that I found helpful. Even if you are working through a book, getting the same lesson presented differently, with different wording and examples, can help.
Wait, what? I know. If you’d told me as a senior at university suffering through formal logic that, at the age of 40, lambda calculus would suddenly become very relevant to my interests, I’d surely have scoffed. But it’s true! Haskell is a lambda calculus, so understanding it in its simplest form (not easiest, but simplest in the sense of “without all the fancy syntax”) can help tremendously. We started our book with a chapter on lambda calculus, but here are some other ways to dive in:
Functional Programming Through the Lambda Calculus OK, so this one is more than a blog post, but I found it very readable. The example code is in Pascal but is well enough explained with reference to lambda expressions that I didn’t find it problematic. Even getting through only the first two chapters will boost your functional programming skills by quite a lot, I’d think.
Some of the posts listed here go beyond basic function application and types. You may find you only understand half the post the first time you read it (or less sometimes, if you’re like me!). That’s cool. What I did is bookmark them and keep coming back to them as I learned more and I was able to recognize how much progress I was making by seeing how much more I understood each time.
It’s a mindset change. I wish I’d known this earlier as it would’ve saved me frustration and doubt, but you kind of need to unlearn what you think you know about coding, then go back to the basics. – This person has the right idea.
Reading Simple Haskell is both a great introduction and a great review/reference to basic Haskell structure and syntax.
There is also this Haskell Cheat Sheet available in several formats, which is a nice touch. It may be more useful for reference/review than learning as a beginner, but it’s nice to have around anyway.
Haskell Basics This is the first lesson in the School of Haskell, and it covers a lot of fundamentals, including (important!) how to read GHCi error messages.
Function Application and Definition This one covers a lot, but there is a ton of examples that help if you follow along with them.
Haskell Functions Take One Argument Well, speaking of terse, Tony Morris can be a bit terse himself, but I think this post makes its point clearly. I believe it can seem like a pedantic point to beginners – that Haskell functions have only argument – but understanding it well is important to understanding partial application, which is ubiquitous in Haskell code.
Types & Kinds Again, a lot of examples here to help you understand the points.
Sum Types This post is a good, not terribly jargon-filled overview with some very nice examples. It’s mostly about sum types with just a bit about product types at the end, presumably because product types seem to be more common in other languages.
We made a types cheat sheet available as a reference for understanding and reading Haskell datatype declarations and type signatures.
The Algebra of Algebraic Data Types This link goes to Part I. There is a Part II and Part III, each covering slightly more advanced topics, as well as a video of a talk the author gave on the subject.
Currying is Delicious I wrote this one, and like some of the ones above, it goes a bit beyond reading basic type signatures. But it’s important to understand currying, and as you get around to understanding kind signatures as well, it’ll help you understand functors, which will eventually help you understand the legendary Monad.
The Haskell Wiki is, like most wikis, uneven in quality and helpfulness, but this page has some nice tips and explanations of some common syntactic mistakes.
A nice concrete example of what recursion is, including the base case.
I also like these two posts from John D. Cook about recursion: Understanding Recursion and Understanding Recursion Part II. “Recursion is about solving a problem in terms of smaller versions of itself.” I am going to disagree somewhat with Cook and, apparently, Paul Graham (if I may be so bold), and say that I did find it helpful to trace the invocations of recursive functions a couple of times (and we do that in the Recursion chapter of our book), but it’s quite correct to say that once you understand what’s going on, you will suddenly find that you almost never write recursive functions yourself and so you don’t think about the process anymore. Instead, you just use
mapor a fold or something and the recursion is built in. Well, at any rate, I found understanding the step-by-step process of how recursive functions work helped me understand what those functions were really doing, especially with folds.
These slides from Gabriel Claramunt’s talk about folds illustrate how folds work well enough that I think they’re helpful even when you aren’t listening to him talk.
Map, Reduce, Fold Yeah, the examples are in Scala, but I found I could follow them even though I don’t know Scala, and I found the recommendations for when to use
Interactive Demonstration of
The problem with most blog posts about functors, applicatives, and monads is less that they have analogies to food items and more that they miss the point that all of those big typeclasses are generalizations of basic patterns. What we want to do is apply and compose functions in the presence of structure, and these are ways of doing it. None of these typeclasses are magic, and they all exist to solve common programming problems. They’re things you might well have written yourself, but in Haskell, we’ve just pulled them out into typeclasses to make them reusable with a lot of different types of structure. I mean, I say “we” but obviously this was done by smarter people than I am.
They did that with monoids, too, and even though you’re thinking “monoid” sounds like some unfortunate disease, it’s a pattern you’re familiar with – addition, multiplication, and list concatenation are all monoids.
The Typeclassopedia is one of the things people told me to read when I was a beginner, and it was way over my head. However, once you’re ready for it, it’s an invaluable source of information about important typeclasses. You might try going through it as you’re working through the NICTA course. Heh.
I haven’t worked through all the posts in this baseCS series (plus I always appreciate a clever title!) yet, but I have loved the ones I have. She has written posts on fundamentals like understanding hexadecimal and linked lists, through databases and fun topics like parse trees and the traveling salesman problem.
If you don’t already know git, you need to. One thing I’d like to note, because this wasn’t very clear to me for a long time, is that git is not GitHub. I use git mostly from the command line, so for me, when I move a repository from GitHub to Gitlab (or vice versa), I change the address of what I’m pushing to and pulling from, but the commands themselves don’t change. The first time I moved something from GitHub to Gitlab, I didn’t realize that would be true, and I thought I’d have to learn new things. Every experienced programmer is probably shaking their heads at me now, but if putting this out in public will prevent any one person from having the same fear, then so be it. That said, I highly encourage you to learn git from the command line. Here are some places to get started.
Read this first, because it’s reassuring and also has links (at the bottom) to the two best sources of understanding git’s underlying model that I know of. I don’t have a preference between them. I strongly urge you to familiarize yourself with the underlying structure of git. Having that model in your head will help you diagnose problems when they arise and use a search engine to find commands that you need. It’s hard to search for git commands if you’re not sure what you need to do, and having an idea of the underlying structure helps you know what you need to do.
This doesn’t explain very much about git’s underlying model, but is a good, quick starting point that explains the most commonly used commands, and it’ll serve as a good reference as you’re learning.
This is a solid introduction to rebasing. My only regret here is that it’s not called “Rebaser” after the awesome Pixies song. Anyway. You may not want to know about rebasing, and you may not like rebasing, but it is something you will probably have to know about at some point, and this is a good explanation.
Let’s talk about git problem-solving. This is about solving a problem you might never have or not have for a long time, it’s true. So why beginner? Because it explains a process for how to solve a problem using terminal commands and git that actually teaches you some useful and valuable things about terminal commands and git that you can use for other purposes, too. It’s not the first thing you should read to learn git, but when you’ve got some of the basics down and are looking to learn more, this one is good. (p.s. MJD’s blog is generally a goldmine of knowledge made accessible.)