3 ms·
For a long while now, I've been trying to write a monad tutorial I'm actually happy to give people as an entry point, and that point is precisely why I haven't
by pdpi 2y ago
For a long while now, I've been trying to write a monad tutorial I'm actually happy to give people as an entry point, and that point is precisely why I haven't put anything out there yet. It's also the reason I keep trying: there's something important to be learnt there in terms of communicating tricky concepts.
- kqr 2y agoI think the lesson is that tricky concepts have to be taught by example. Some theoretically-bent people can read a definition and generate their own examples, but most people I've met need to be presented with and taught one example at a time. After a while, they just get it and the abstraction falls into place. https://two-wrongs.com/the-what-are-monads-fallacy.html https://two-wrongs.com/the-what-are-monads-fallacy.html
- pdpi 2y ago> I think the lesson is that tricky concepts have to be taught by example. The bigger insight, for me, is that they also have to be taught by counter-example. E.g. it's easy to find Functors that are neither Applicatives nor Monads (usually, because you can't produce a reasonable definition for `return`). It's surprisingly hard to find a non-contrived example of a Functor that is also an Applicative, but *is not* a Monad. Without that counter-example, it's very tricky to build the intuition for where the boundary lies.
- andrepd 2y agoNow I'm curious: what's this non-contrived example?
- pdpi 2y agoValidation. You can think of it as shaped like Either [Error] Value, but the implementation is different. Consider this example: pure . Config <$> validate option1 <*> validate option2 <*> validate option3 Either would short circuit on the first validation error. There’s two interesting things here though: there are no data dependencies between different validations (so we don’t _need_ a monad), and it’s useful to accumulate errors to know if both option1 and option3 failed to validate (so we don’t _want_ the Either monad’s short circuiting behaviour). The implementation is pretty straightforward, too!
- chongli 2y agoSome theoretically-bent people can read a definition and generate their own examples This is what mathematical training taught me to do. It's something I wish everyone could learn to do but high school is too short to teach it to most people.
- hansvm 2y agoA technique I've had a reasonable amount of success with when teaching formerly imperative programmers is focusing on the constraints that force something like a monad to exist (the "you could have invented it yourself" teaching approach): 1. One of the main points of functional programming is that your computations are the results of pure functions -- enabling niceties like thread-safety, type-safety, .... 2. That view of the world is imperfect because some interactions (like responding to user input) require a _sequencing_ of events. 3. Imperative languages accomplish that task easily. They just write the events in the sequence they want them executed. With constraint (1) though, your only option for sequencing is function composition. Whatever interface you choose, it _has_ to use composition somehow. 4. Monads are one of many possible solutions, and they're the one we happen to have standardized on. They're convenient because you can wrap up all that compositional nonsense into something that feels a lot like the mutable objects you're used to when you actually apply them in your code. That explanation skips over a lot of details, but it helps people build the initial spark of intuition to attach all the rest of the ideas onto. The mechanics of a monad, their capabilities, the available syntax, ..., don't seem to be the main stumbling block in my experience.