Teaching Haskell Through Memes

Simon Baars
6 min readNov 6, 2023

In University, I fell in love with Haskell.

God, that language is neat.

After finishing University, I was asked by the professor teaching the Haskell course to stick around and help out. For the next four years, I’ve been doing the Haskell introduction of the Software Testing course at the University of Amsterdam. And every year, my slides evolved… till there was nothing left but memes.

Nowadays, we’re teaching the gen-z generation. Being digitally native, they are very fast to catch on to logical concepts. However, that sometimes comes with a somewhat reduced attention span. That’s not a problem though! The trick is to present short & snappy content, instead of slides filled with technical jargon (those never worked anyway).

For this article, I’d like to share what my Haskell presentation has become after four years of improving the slides and overall storyline. Hopefully, by the end, you will have learned why Haskell is so cool, and memorize it through the memes within.

Let’s learn some Haskell!

Haskell is incredibly fun. But there’s a dark side to it: Haskell is applied mathematics. Generally, Haskell excels at implementing mathematical formulas. Doing that sometimes requires dissecting complicated mathematical theory captured in research papers and translating it to valid Haskell code. It’s the evil Kermit lurking behind Haskell.

Starting out

Let’s get this Haskell course off the road. Let’s boot up the Haskell console (GHCi) and start simple:

1 + 1 = 2. OMG.

And I can see you think: booooring.

You’re right. There’s a better way to do that:

SUCC! (succ stands for successor, and it gives the successor to any enumerable value, including numbers)

Amazing. Don’t confuse the succ with the zucc, btw.

Where to find this amazing succ?

So how could we have known about such amazing functions like succ and others like it? Well, that’s easy. We just Hoogle it.

Hoogle is an incredibly flexible search to find out about Haskell functions:

Based on this search result, we find out what the function does (text in grey), whether we need to import something (text in green), and what the type is (text after the double colon).

In this case, we’re dealing with a function that takes an enumerable (Enum) aliased as a, and returns something with the same type (in the expression a -> a, the first a is the function argument and the second a is the response type).

All this theory to increment a value by one?

Now, don’t get impatient. We’re working up to the great reveal: everything is a function.

What does “everything” mean? Exactly what it means! Everything.

And that’s such a powerful concept in Haskell. Let’s zoom in. Using :t in GHCi, we can find out the type of a function:

Yeah, we already knew that from Hoogle. But now for the great reveal. That number, 1, which we’ve been feeding to the function, is also a function in itself. It’s a function that has no arguments and returns a number:

Wait, but if 1 is a function that returns a value of type Num, and succ takes a value of type Enum, then how are the two compatible?

Well, that’s where we get into the totally extremely complicated Haskell type chart:

Actually, when we created the function 1, Haskell did not yet know whether it was an Int, an Integer, a Float, or a Double. However, Enum, the type accepted by succ, only inherits Integral, which can be either an Int or an Integer. Since Haskell is totally smart, it figures out that you must mean Int or Integer with 1, and proceeds with that in mind (so we won’t need typecasting making our logic needlessly complicated).

The funny thing is, all we have really talked about so far is simply 1 + 1. But that extremely simple expression learns us a lot about powerful mechanics of Haskell.

Get through the tedious information, get rewarded

Now, the memes are just a vessel to take us through the tedious first steps of learning Haskell. It’s like math in high school: it all seems pointless till you’re actually able to apply it in your job. Knowing that everything in Haskell is a function is useless until you get into partial function application, and then it suddenly makes sense.

Let’s go back to one plus one once more:

Wait, what the heck? Why is the plus operator in front of the operants?

Well, because of course, plus is just a function too (just sneakily defined as infix):

Having learned that everything is a function, we know the following:

  • (+) is a function that takes two Num arguments and produces a Num.
  • Each 1 in the expression is a function on its own, each returning a Num.
  • (+) 1 is a function that takes one Num argument and returns a Num (partial application):

So now, if we apply the function (+1) on 1, we complete the function application:

Where are my memes?

Sorry, I kinda trailed off there. But this stuff is really cool! And super powerful.

And that’s just 1 + 1!

Anyway, if you’re serious about learning Haskell, I can recommend checking out Learn You a Haskell: http://learnyouahaskell.com/introduction. It has a great sense of humor, and awesome illustrations like this guy:

But I mainly wanted to show my work of perfecting a presentation through several years, and ending up using an “always has been” meme to illustrate a super powerful Haskell concept.

Cheers!

--

--

Simon Baars

Yet another guy making the internet more chaotic with random content.