Advent of Code 2020 in Haskell


Last month I participated in Advent of Code, an advent calendar with a new programming puzzle each day. It was my first year, and I'm sure it'll not be the last!

It all started a fateful day in late November, in a nameless Twitch Chat, where I ranted about not having enough good excuses to practice Haskell. Then, someone suggested I give Advent of Code a go, which was starting in a week. Long story short, I spent around 30 minutes (or more 1) every day solving programming puzzles for 25 days.

Most of the problems don't require any advanced knowledge, and let you solve them in any way you prefer. The difficulty slowly ramps up each day, letting you get into the flow calmly.

You can see my subpar solutions here.


Here are some thoughts I have about it:

I'm quite happy I participated, as I've seen a real improvement in my knowledge of Haskell. Looking back at my solutions for the first days I can see a lot of things I could have done in a different and more elegant way. What I did was, after solving each of the puzzles, go into the r/adventofcode solution megathread to read other people's solutions in Haskell. This way I found what the idiomatic way to have solved the problem was.

A thing I discovered: Hoogle is your friend when working with Haskell. And what a friend it is! Also, using hlint is pretty nice to find how to write common things in a more elegant way.

Slowly, day after day, I started to become more comfortable with the different aspects of Haskell, and I managed to start using some of the more advanced concepts. There's still a lot of things I don't know how to use correctly, but I can now look at other people's code without feeling overwhelmed. Not an impressive achievement, but feels good to see all of the <$>, >>=, *> and be able to understand what each of those mean.

One of the first days I tried using regexes to parse the input, but it felt very clunky. I switched to making my own parsing functions for the next days. This worked alright, but it was tiresome to implement something different everyday. It took me until day 14 to realize that Parsec was the answer to my prayers. I knew it existed, but I had been putting it off for fear of how long it would take to learn. Turns out, it's not that complicated! I'm starting to realize that most things in Haskell actually do make sense and are very much worth the learning curve, however steep it might be.

A thing that surprised me is how there appears to be a function for basically anything you might want to do. It kinda feels like the Good ol' C-x M-c M-butterfly XKCD. Every time I want to do something, hlint will be like: "Why not use concatMaybe instead?", or someone on the solutions megathread will have a 30 line solution with more imports than functions, while I'm sitting with a 300 line long solution.

I have also realized that on my last post about Haskell I practically knew nothing. I feel like there's two separate learning curves with Haskell, one for understanding the syntax, and one for learning all of the commonly used typeclasses and functions in the standard library. The first one is already a challenge when coming from only writing C-like languages, but is manageable after seeing a few examples and playing around a bit. The second one though... The second one is a beast. Reading through the Typeclassopedia and seeing other people's solutions has helped, but there's just sooo much stuff there to learn, and it's all interconnected.

In conclusion: Haskell and Advent of Code are both very cool, and I really recommend them.


Definitely more than half an hour