Functors, Applicatives, and Monads: The Scary Words You Already Understand

21 points by nemin


mrak

Having learned Haskell before using rust, gleam, or elm, I can relate to the steep learning curve of the mathematical jargon used everywhere in Haskell. As I was learning I constantly had to mentally rename the category theory concepts into more relatable programming terms. I felt like I stumbled far more than required to understand what was effectively just names for abstractions that I already understood but just didn't know there was a specialized term for.

Terms like monads, monoids, functors, bifunctors, applicatives, arrows, etc are all incredibly alienating if you are not already familiar with them.

However, having now learned and understood the bounds of these abstractions and their associated functions and infix operators in Haskell I GREATLY prefer their ability to be used with entire classes of types (TypeClasses) instead of the gleam/rust/elm way of having per-type functions (Map.map, Array.map, Option.map, etc). In non-Haskell FP languages I will frequently want to use a generalized pattern of, say, Applicatives to chain transformations through a Maybe/Option here and a Result/Either there, but keep getting caught up needing to remember exactly which type I am using to call the associated function or triggering the LSP to find it. This is, in essence, the power of typeclass abstraction that languages like Haskell can provide: lots of differently "shaped" structures start to look and behave the same conceptually when applying things to data passing through them.

I'm convinced if I learned gleam/elm/rust first I would have a different impression, but having gone through the learning-through-abstraction experience I now appreciate its power.

Corbin

There really ought to be a monad-tutorial checklist. The biggest issue is working in Elm, which deliberately cannot support the level of abstraction required. The next two issues are classic omissions of monad tutorials: eliding the algebraic laws and claiming that functors are always containers for values.