Monads for free

Two weeks ago I started a new job as a Haskell software engineer. My expectation was to suffer immensely from impostor syndrome, especially during the first few weeks. Surprisingly, I feel pretty comfortable with my abilities so far!

The first week was all spent on onboarding. We got a crash course in how to use the product that we'd be working on/selling/giving customer support for. Us programmers got dumped in our teams after the first week, whereas support/sales are getting more extensive training.

I still have some onboarding presentations later this week, but last week I was pretty much left alone with a list of "good first issues" to work on and a way to reach my supervisor if I had any questions, which has been going extremely smooth so far.

The fact that the code is readable and documented is a major factor in this. At my previous company, this was not at all the case. I was able to pretty easily dive into one of the Haskell projects. Much more easily than I had originally expected!

The problem

I feel like I barely understand what a monad is. Like I am one bad explanation away from having my understanding of the concept shattered. My experience with Haskell documentation is... not great. This experience is not helped when I come across a library like free.

In this case I came across a section of code like this:

type Action = Free ActionFree

So naturally I attempted to find out why Free is needed here, which led me down a rabbit hole of scary-sounding math terms (of which I did not grasp more than half, if I'm being extremely generous to both myself and the math community).

A Monad n is a free Monad for f if every monad homomorphism from n to another monad m is equivalent to a natural transformation from f to m.

Bless you. Now to me, a programmer without an extensive background in maths, this person is speaking the language of the gods. Here I got sidetracked and spent about an hour on finding out what a "monad homomorphism" is, and learning about related concepts. In the end, this turned out to be completely unnecessary, because someone was able to explain it to me.

What's bad about this

It left me so confused and abandoned. I am expected to know lots of interdependent and abstract mathematical concepts and related terminology, because everything is defined in terms of everything else. This makes Haskell in general very intimidating to get into, especially compared to a language like Rust, where concepts are explained in plain English.

Poor documentation is a big issue for a lot of programming languages, especially the more functional ones. Often, it seems to be the assumption you are already familiar with the concepts and you're just looking for a little refresher on what the exact signature of some function is, with the explanation seemingly serving as little more than decoration.

I often end up on stack overflow or a random blog post explaining a random concept when I'm trying to find out what something I read in the generated documentation actually means. Documentation being short and to-the-point is great, if you already know what you are doing. If you don't, and you happen to learn by doing instead of by reading, Haskell documentation usually kinda screws you over and makes you read everything anyway, which is discouraging to say the least.

The upside, I guess?

Learning Haskell basically on-the-fly is close to impossible. Haskell will let you know when you are out of your depth and forces you to learn hard. Confusion and painful teaching moments do work. If you need to spend more energy to parse something you have to learn, that helps you remember. This inspired the design of Sans Forgetica, for example. Note that Sans Forgetica does not actually seem to work, however.

Anyway, if you try to misuse something you don't know enough about to use properly, GHC will bully you. You might spend hours trying to interpret the error message, which makes learning Haskell even harder.

Some overly harsh criticism

It also does not help that traditionally, mathematicians absolutely suck at naming things.


Having said all this, I do like Haskell. It looks nice, it reads well (once you know what everything means, that is) and it teaches you a whole lot about other ways to program, if you are used to more imperative languages.

It definitely wants you to be motivated to learn, though. And to be capable of handling frustrating scavenger hunts through wikipedia articles, generated documentation, random blog posts, the source code of the library you're trying to use and obscure errors, both compile-time and runtime.