3 ms·
You can just say that a monad is a way to chain operations together by wrapping a value. The consumer usually doesn't need to know the gore-y details of how a m
by PartiallyTyped 3y ago
You can just say that a monad is a way to chain operations together by wrapping a value. The consumer usually doesn't need to know the gore-y details of how a monad is implemented, only the purpose of it and how to use it.
A Maybe monad just says the value may be Something(x) or Nothing. You won't know until you run the computation. If you use flatmap and give a function that takes an x and gives a Maybe[x], the monad will first map into Maybe[Maybe[x]] and then flatten into Maybe[x]. The computation has not happened until you execute it and internally all the functions have been composed together.
A List[A] just says, give me a function A->List[B], and I will flatmap (flatten `compose` map) it. So it maps each element into a possibly empty list of Bs, and then flattens it by concatenating them.
You can define your own monads, and as long as they obey the laws of monads, you get a bunch of stuff for free.
- icrbow 3y agoYou say "by wrapping a value" and then confuse it with the wrapper right away. No, monads are not wrappers. Some wrappers are monads, but not all. inb4, monads are not pipes either.
- PartiallyTyped 3y agoSure, a monad is a type constructor. The constructed type allows you to compose transformations. Each monad constructs a type that behaves differently and expects different things, but in general; the monad is defined by a unit/point/return function which brings a value into the monadic context, and a flatMap function aka bind, which further breaks down to “flatten after map”. So List[_] is a type constructor, given a type T, it produces a List[T], which defines some transformations. Return creates a single element list, and flatmap takes the A->[B] applies it everywhere and then concatenates. The nice thing about the wrapper analogy is that even though it is technically wrong, it is easier for people to get it because it follows naturally from OOP and it is a sufficiently useful mental model imho.
- jghn 3y agoIMO the spirit of this answer is a big part of the problem. This might not be exactly what the GP was saying but I've found you can quickly get a dev up to speed with a "good enough" sense of what a monad is. One that'd cover a vast majority of their needs, at least in the early going. But then there are always people who start popping in and pointing out how those definitions aren't quite right. Which is true. But does it matter *for practical purposes* to give a dev a useful for now mental model that they can then use to figure the rest out later? I'd say no.
- PartiallyTyped 3y agoThe intention of the comment was just to give a good enough model so that devs can just get going :)
- jghn 3y agoYes, sorry, I was agreeing with you & not the person who responded.
- bPspGiJT8Y 3y agoThen why not just say that a monad (instance) is a type `t` which implements `bind :: t a -> (a -> t b) -> t b`? It's as down to earth and down to the point as it gets, and each time a new dev thinks out a code path which would lead to `t b` they'd remember `bind`. No need for containers metaphors at all.
- PartiallyTyped 3y agoWhat’s a `type`? What is `t a`? How do I get `t a`? How does `t b` become `b` when I bind again? Where is `b` after I bind? What about the reader monad and the state monad? Those have different signatures, so what gives?
- icrbow 3y agoThis. Just point to the definition in your language (NOT the category theory, unless that's what you're coding in). In Haskell, a Monad is a type class with a method `bind`. In Scala that would be a `flatten` or whatever. If a person who's asking doesn't yet know what the "type class" is, or how to read signatures, your "monad tutorial" would not make much sense anywat. Guide them to learn the prerequisites first.