Haskell for Scala Developers: Part 2 — Type Classes and Implicits

Part 1 was the friendly part of the comparison. Functions, ADTs, options, newtypes — Scala does these well, Haskell does them slightly better, and the gap is small. This post is where the gap becomes wide.

Implicits in Scala have an origin story that I think gets understated. They are not "a way to thread context through your code" — that's how we use them, but it's not what they're for. Implicits were Scala's mechanism for doing the work of Haskell's type classes inside a language that doesn't have them. Wadler and Blott published the original Haskell type-class paper in 1989; Odersky designed Scala's implicit-parameter machinery explicitly so the same shape of code could be written on the JVM. The mechanism was reverse-engineered from the Haskell feature it was meant to imitate.

Scala 3's given / using is the cleanup. With the benefit of every Scala-incoherence horror story the community has collected, the language renamed the keywords, narrowed the resolution rules, and tried to hide the implicit-conversion traps that were eating juniors alive. It is much better than what it replaced. And it is still trying to be a thing that Haskell already is.

That's the post. Less ceremony, fewer traps, no implicit-conversion magic, instance coherence by default. We'll walk it from the simplest case — Eq, Show, Ord, same words and same job in both languages — through resolution and coherence, through the type-system feature both languages had to invent for this (HKTs), through the Functor/Applicative/Monad ladder on our own type, and ending with deriving. I'll assume you can read Cats fluently. I'm not going to re-teach the abstractions.

Previous in series: Part 1 — Functions and Data.

Haskell for Scala Developers: Part 1 — Functions and Data

There's a popular way to write this kind of post — a feature-by-feature comparison table, with checkmarks and a sentence per row. I'm not going to do that. What I want to do instead is take the parts of Scala that you already write idiomatically — case classes, sealed traits, Option, Either, the occasional extends AnyVal for a typed id — and show you what happens when the language stops apologizing for them.

That's the main thread of the series. Most of what made me love Scala is exactly what Haskell gives you, minus the JVM cost, minus the OOP escape hatches, and minus the long-running argument inside the Scala community about what good Scala even looks like. If you want the longer version of why I'm writing this at all, it's in The Rise and Fall of Scala.

This first post is the easy one. Functions, data, pattern matching, options, newtypes — all the things you already type twenty times a week. The translation is mostly mechanical. The interesting part is the small set of frictions that disappear when the language stops compromising on them.

Haskell Was Waiting for This

Every few months someone announces "the best language for AI." Usually it's Python, sometimes TypeScript, occasionally Rust when the mood is right. I want to make a less fashionable claim: if you care about shipping code that an LLM helped you write, and you want to be confident it actually works, Haskell is quietly the best fit in 2026.

Not the trendiest. Not the easiest to hire for. The best fit. Let me explain.

A Philosophy for Personal Media File Storage

If you've been taking photos and videos for more than a few years, you've probably accumulated a mess. Files from phones named IMG_20230415_143022.jpg, Pixel cameras producing PXL_20230415_143022.mp4, screenshots labeled Screenshot_2023-04-15, and whatever your old point-and-shoot decided to call things. They're scattered across devices, cloud services, and backup drives — some with correct dates in their metadata, some without, some with dates that are just wrong.

At some point you try to organize them. You create folders: "Vacation 2023", "Family", "Work Events". It feels productive for a week. Then a photo belongs in two folders, or you can't remember whether that dinner was "Family" or "Friends", or you find a folder called "Misc" with 400 unsorted files from three years ago.

I went through this cycle a few times before stepping back and rethinking the problem.

Eventium: Design Decisions and Internals

In the previous post, I walked through building a banking system with eventium — covering projections, command handlers, process managers, and read models from the user's perspective. This post goes one layer deeper: how the event store is structured, what guarantees it provides, and why things are built the way they are.

Each section starts with a problem that comes up when you try to build a production event store, then shows how eventium addresses it and what tradeoffs that involves.