[HN Gopher] Functors, Applicatives, and Monads
       ___________________________________________________________________
        
       Functors, Applicatives, and Monads
        
       Author : abhi9u
       Score  : 74 points
       Date   : 2025-03-28 11:46 UTC (2 days ago)
        
 (HTM) web link (www.thecoder.cafe)
 (TXT) w3m dump (www.thecoder.cafe)
        
       | rthnbgrredf wrote:
       | This reminds me of
       | https://www.adit.io/posts/2013-04-17-functors,_applicatives,...
       | 
       | I think over the recent years, there's been a rise in typed
       | languages that support functional programming like TypeScript and
       | Rust. It will be interesting to see if this trend continues in
       | the context of AI assistant programming. My guess is that it will
       | become easier for beginners, and the type systems will help to
       | build more robust programs in cooperation with AI.
        
       | personperson69 wrote:
       | the bit at the end is quite rude of the haskeller responding but
       | I also think they're largely right; another monads explained
       | through boxes tutorial is not gonna help anyone. In fact it's
       | really a step in the wrong direction. Using a few different
       | monads is where to start.
        
         | Vosporos wrote:
         | Was it rudeness or honesty without malice? The "monad tutorial"
         | instinct is a well-documented fallacy. In my culture we don't
         | whitewash our opinions to make them palatable to someone who's
         | obviously doing something wrong in a known way.
        
           | redlohr wrote:
           | On first read, I was prone to agree with the author -- why
           | put down someone seeking your input? Then I read your comment
           | and went through it again. After a re-read I think you have
           | it right. The response was direct, and perhaps quite cutting
           | to the author who had devoted significant time to the article
           | only to be told they're one of hundreds who have made the
           | same mistake. But the only denigrating in the linked blog
           | article seemed to be the grouping with others who had fallen
           | into the same trap.
        
       | jerf wrote:
       | Unfortunately, while you may not have appreciated the tone of the
       | Haskell interaction, they are correct in their assessment from a
       | factual perspective. This explanation propagates a number of
       | misunderstandings of the topics well known to be endemic to
       | beginners.
       | 
       | In particular, I observed the common belief that functors apply
       | to "containers", when in fact they apply to things that are not
       | containers as well, most notably functions themselves, and it
       | also contains the common belief that a monad has "a" value,
       | rather than any number of values. For instance, the "list monad"
       | will confuse someone operating on this description because when
       | the monad "takes the value out of the list", it actually does it
       | once _per value_ in the list. This is the common  "monad as
       | burrito" metaphor, basically, which isn't just bad, but is
       | actually wrong.
       | 
       | I'm not limiting it to these errors either, these are just the
       | ones that leap out at me.
        
         | adamddev1 wrote:
         | Bartosz Milewski argues that we can think of functions etc. as
         | containers as well, if you check out his YouTube lectures on
         | Category Theory for Programmers. Lists and functions "contain"
         | a type.
        
           | jerf wrote:
           | A term's utility comes from its ability to separate things
           | into different categories. A definition of "container" that
           | includes everything is therefore useless, because if
           | everything a container, there is no information in the
           | statement that something is a container.
           | 
           | In Bartosz's case he's probably making the precise point that
           | we can abstract out to that point and that at a super, super
           | high level of category theory, there isn't anything that
           | isn't a container. However, that's a didactic point, not a
           | general truth. In general we programmers generally do mean
           | something by the word "container", and functors can indeed
           | include things that are therefore not containers.
           | 
           | Moreover, I would say it's not what the author was thinking.
           | The author is not operating on that super high level of
           | category theory.
        
           | edflsafoiewq wrote:
           | A list [b] is a container for bs indexed by integers. A
           | function a->b is a container for bs indexed by as.
        
             | cluckindan wrote:
             | [b] is more like a blueprint for a container, and a->b is
             | more like an assembly line of containers.
        
             | rebeccaskinner wrote:
             | > A function a->b is a container for bs
             | 
             | Anecdotally, this is one of those things that's trivially
             | true to some people, but really hard for other people to
             | internalize. I think it's why the "container" can lead
             | people astray- if you haven't internalized the idea of
             | functions as being indexed by their argument, it's a really
             | mind twisting thing to try to make that leap.
        
               | n_plus_1_acc wrote:
               | I can recommend learnung some scala, where HashMap
               | extends PartialFunction
        
               | magicalhippo wrote:
               | If I give you a function "f(x) := 3 * x", is it really
               | that useful to talk about it as a container of the
               | natural numbers?
               | 
               | The reverse though _is_ useful, a container looks like a
               | function that takes one or more indices and returns a
               | value or element.
        
               | rebeccaskinner wrote:
               | I think that understanding the (moral) equivalence is
               | useful in both directions. In particular, I think helping
               | people understand the "function-as-container" analogy is
               | a useful way for people to understand pure functions-
               | another thing that's conceptually simple but a lot of
               | people struggle to really wrap their mind around it.
        
               | mncharity wrote:
               | > really hard [...] leap
               | 
               | Two stepping stones might be array getters (function
               | that's array-ish), and arrays with an indexed default
               | value function (array that's function-ish)?
        
               | rebeccaskinner wrote:
               | I've recently started writing a series of blog posts (htt
               | ps://rebeccaskinner.net/posts/2024-10-18-dictionaries-
               | are...) trying to explain the idea and my approach has
               | been to explain the idea using comprehensions. I haven't
               | had a lot of people review the post yet, and I still have
               | at least one if not two more follow-ups before it's done,
               | so I'm not yet sure how well the idea will land.
        
         | hajile wrote:
         | Functions are just containers of calculations (the whole "code
         | is data").
         | 
         | I don't know why lists as values in a container would be
         | confusing. Lots of very popular languages literally have box
         | types which may not be exactly the same, but show that
         | expecting containers to potentially commission complex data
         | isn't unusual.
        
           | fn-mote wrote:
           | > I don't know why lists as values in a container would be
           | confusing.
           | 
           | The GP makes it pretty clear - the misunderstanding is that
           | there is one value in a container. A list has many.
        
         | T-R wrote:
         | Thinking too concretely about monads as boxes might make the
         | behavior of the ListT monad transformer seem a bit
         | surprising... unless you were already imagining your box as
         | containing Schrodinger's cat.
         | 
         | I can definitely understand the author taking offense to the
         | interaction, but now that a lot more programmers have had some
         | experience with types like Result<T> and Promise<T> in whatever
         | their other favorite typed language with generics is, the
         | box/container metaphors are probably less helpful for those
         | people than just relating the typeclasses to interfaces, and
         | pointing out that algebraic laws are useful for limiting the
         | leakiness of abstractions.
        
         | noelwelsh wrote:
         | One can start with a partial explanation and expand it cover
         | all the cases as learning progresses. This is how most learning
         | takes place. I expect your primary school teachers introduced
         | numbers with the natural numbers, instead of, say, transfinite
         | numbers. Students learn Newtonian physics before relativity.
         | It's completely fine to build an understanding of monads as
         | operating on containers, and then expand that understanding as
         | one encounters more cases.
        
       | randomstate wrote:
       | Coming from non-Haskell background, it took me a good while to
       | undestand that `Just` is a constructor specific to the `Maybe`
       | type. Found this for a quite nice answer:
       | https://stackoverflow.com/a/18809252
        
       | lihaoyi wrote:
       | For some reason everyone likes to talk about Monads, but really
       | the other types here are just as interesting. For example,
       | Applicatives are less dynamic than Monads in that you can't
       | `flatMap`/`bind` to decide on the "next" thing to evaluate based
       | on the previous value, but in exchange you get a "static" tree
       | (or graph) of Applicatives that lends itself much better to
       | static analysis, optimization, parallelism, and so on.
       | 
       | IIRC Haxl (https://github.com/facebook/Haxl) uses Applicatives to
       | optimize and parallelise remote data fetching, which is hard to
       | do with Monads since those are inherently sequential due to the
       | nature of `flatMap`/`bind`. My own Mill build tool (https://mill-
       | build.org/) uses an applicative structure for your build so we
       | can materialize the entire build graph up front and choose how to
       | parallelize it, query it, or otherwise manipulate it, which is
       | again impossible with Monads since the structure of a Monad
       | computation is only assembled "on the fly" as the individual
       | steps are being evaluated. "Parallel Validation" where you want
       | to aggregate all failures, rather than stopping at the first one,
       | is another common use case (e.g.
       | https://hackage.haskell.org/package/validation or
       | https://typelevel.org/cats/datatypes/validated.html)
       | 
       | Monads seem to have this strange aura around them that attracts
       | certain kinds of personalities, but really they're just one
       | abstraction in a whole toolkit of useful abstractions, and there
       | are many cases where Applicative or some other construct are much
       | more suited
        
         | kqr wrote:
         | > Monads seem to have this strange aura around them that
         | attracts certain kinds of personalities
         | 
         | Historical accident.
         | 
         | There was a time, not very long ago, when we didn't know
         | applicative functors were a useful separate subset of monads.
         | We thought full monads were needed for all the neat things that
         | applicatives are sufficient for.
         | 
         | During this time, lots of ink was spilled over monads. Had we
         | invented applicative functors a little earlier, they would
         | probably have gotten more of the spotlight they deserve.
         | 
         | -----
         | 
         | I also think people underappreciate the humble
         | semigroup/monoid. But this is not historical accident, it is
         | just that it seems to simple to be useful. But it _is_ useful
         | to be able to write functions generic over concatenation!
        
           | kccqzy wrote:
           | Indeed it was not long ago that in the language there was no
           | relationship at all between the Applicative class and the
           | Monad class. And then one release Applicative was made the
           | superclass of Monad. That's the reason why we have sequence
           | and sequenceA, sequence_ and sequenceA_, liftM and fmap, ap
           | and <*>, liftM2 and liftA2, return and pure, traverse and
           | mapM etc. All these pairs of functions do the same thing but
           | are duplicated for historical reasons.
           | 
           | This historical accident has, IMO, made the language harder
           | to teach.
        
         | yodsanklai wrote:
         | > Monads seem to have this strange aura around them that
         | attracts certain kinds of personalities
         | 
         | I don't know if it's a matter of personality or aura. Monads
         | are the first unfamiliar/complicated abstraction you're bumping
         | into when learning Haskell. You can't do anything IO without
         | monads, and they're not straightforward like functors or
         | monoids. This is probably why there are more discussions about
         | monads.
        
       | behnamoh wrote:
       | monads are the MCP of functional programming--no one really knows
       | what they are but everyone writes an article about them using
       | analogies that break when you actually use them in practice.
        
         | aklein wrote:
         | What is MCP?
        
           | marcus0x62 wrote:
           | Model Context Protocol. It is a way to give an LLM access to
           | an API. There's a lot of hype about it right now, and, thus,
           | a great many half-baked articles floating around.
           | https://www.anthropic.com/news/model-context-protocol
        
         | chowells wrote:
         | Nah. Lots of people know what monads are. And critically, they
         | don't write monad explainers.
         | 
         | This is because if you understand the fundamentals well enough
         | to understand an explanation, monads are so trivially
         | straightforward that the definition is 100% of the explanation
         | you need. Learn about how Haskell denotes types. Learn about
         | higher-order functions, higher-kinded types, parametric
         | polymorphism, and bounded polymorphism. Once you are
         | comfortable with what all of those do in Haskell, Monad is a
         | way to bound polymorphism with a couple extra expectations
         | about how things behave. It takes about 5 minutes to explain
         | and show a bunch of examples.
         | 
         | But before you're comfortable with those parts, it's like
         | trying to explain exponentiation to someone who doesn't
         | understand addition. People who understand exponentiation don't
         | do that. They don't try to use analogies. They say "you need to
         | learn about addition first, then multiplication. You can learn
         | about exponentiation after that."
        
           | BoiledCabbage wrote:
           | > Learn about higher-order functions, higher-kinded types,
           | parametric polymorphism, and bounded polymorphism.
           | 
           | Except that's not the case because most people know all of
           | those concepts from their main language, and don't know what
           | a monad is.
           | 
           | Higher order functions yup. A function can take a funtion as
           | an argument and correctly assign the argument type (unless C
           | where you can finagle it but it's not first class).
           | 
           | Higher-kinded types? Yup. Prettt much half of "generics".
           | Taking C# that essentially the idea that List<T> is a "type
           | constructor" that allows you to construct a type. If you
           | specify Integer as the T you can say something like
           | List<Integer> and you get a type which is a list of integers.
           | 
           | Parametric polymorphism? Yup. When defining function - for
           | example using List<T>. You can define the implementation of
           | the function using the generic parameter "T" and not have to
           | specify if you are defining the implementation on a list of
           | Integers or a List of String, and the single implementation
           | will work for all of them.
           | 
           | Bounded polymorphism? Yup. Again using C#, you can specify a
           | restring on the "T" type parameter. Instead of saying "T" can
           | be any type at all, you can add a "where" clause that says
           | "T" must implement the ISerializable interface, or it must be
           | a subclass of Foo class.
           | 
           | So most people will read this list. And say "huh, I guess I
           | do already know all of those concepts but by different
           | names." But that doesn't mean they understand Monads
           | conceptually, when to use them nor why. Even if those things
           | are required to read the Monad definition, there is more
           | there.
           | 
           | A rough analogy, but it's like saying people know the visitor
           | or facade design pattern just by reading their type
           | signature. Oh and if instead of having intuitive names their
           | names useless names like "foblax" and "grobalum" design
           | patterns.
        
       | burlesona wrote:
       | I feel like Haskell is easier to use than it is to explain, and
       | in my experience a lot of these kind of tutorial / explanations
       | actually make things seem harder and more complicated than just
       | working with the concepts and observing what they do. (This one
       | included.)
        
         | fellowniusmonk wrote:
         | Why are there so few practical, example and code driven
         | tutorials? I've never run across a succinct "build Twitter with
         | Haskell" in the wild.
        
           | rrgok wrote:
           | Yes, I really need a real word Haskell project simple enough
           | to understand all the math concept. Like, I don't know when
           | to implement the Monad type-class to my domain data types.
           | For example, taking the twitter example, if I have Tweet data
           | type:
           | 
           | - should I implement the Monad, Applicative or Functor type
           | class?
           | 
           | - How would that help in the big picture?
           | 
           | - What if I don't do it?
           | 
           | All these funny example of boxes, burritos or context doesn't
           | not help me solve problems.
           | 
           | Take for example Monoid, I understand (partially maybe) that
           | it useful for fold (or reduce) a list to a single value.
        
             | wavemode wrote:
             | > Yes, I really need a real word Haskell project simple
             | enough to understand all the math concept
             | 
             | There actually is a book with precisely that title, which
             | provides what you're asking for:
             | https://book.realworldhaskell.org/
             | 
             | > Like, I don't know when to implement the Monad type-class
             | to my domain data types
             | 
             | A concrete type (such as your Tweet type) can't be a Monad.
             | Monad is implemented on generic types (think: `MyType a`,
             | where `a` can be filled in with a concrete type to produce
             | e.g. `MyType Int` or `MyType String`).
             | 
             | Most monads are data structures like list `[a]` or
             | structures which provide context to computations like
             | `State s a` or `Reader r a`
        
             | T-R wrote:
             | > should I implement the Monad, Applicative or Functor type
             | class?
             | 
             | I struggled with this when I first learned Haskell. The
             | answer is "yes, if you can". If you have a type, and you
             | can think of a sane way to implement `pure`, `fmap`, and
             | `bind` _that doesn 't break the algebraic laws_, then
             | there's really no drawback. Same for any typeclass. It
             | gives users access to utility functions that you might not
             | really have to document (because they follow a standard
             | interface) and you might not even have to maintain (when
             | you can just use `deriving`).
             | 
             | Doing so will let you/users write cleaner code by allowing
             | use of familiar tools like `do` notation, or functions from
             | libraries that say they'll work for any Monad. It saves you
             | from coming up with new names for those functions, and
             | saves users from having to learn them; if I see something's
             | a Monad, I know I can just use `do` notation; if I see
             | something's a Monoid, I know I can get an empty one with
             | `mempty` and use `fold` with it. As long as it's not a
             | really strange Monad, and it doesn't break any laws, it
             | probably just works the way it looks like it does.
             | 
             | If you can define `bind` et. al., but it breaks the laws,
             | it means the abstraction is leaky - things might not work
             | as expected, or they might work subtly differently when
             | someone refactors the code. Probably don't do that.
             | 
             | If you don't implement a typeclass that you could have, it
             | just means you might have written some code where you
             | could've used something out of the box. Same as going
             | through old code and realizing "this giant for-loop
             | could've just been a few function calls if I used
             | underscore/functools or generators".
             | 
             | That said, it's not too common to stumble on a whole new
             | Monad. The Tweet type probably isn't a Monad - what does it
             | mean for a Tweet to be parameterized on another type like
             | `Int`, as in `Tweet<Int>`? What would it mean to
             | `flatMap`(`bind`) a function like `Int -> Tweet<String>` on
             | it? A Tweet is probably just a Tweet. On the other hand,
             | it's a little easier to imagine what a `JSON<Int>` might
             | be, and what applying a function like `Int -> JSON<String>`
             | to it might reasonably do. Or what applying an `Int ->
             | Graph<String>` to a `Graph<Int>` might do.
             | 
             | Most Monads in practice are combinations of well known
             | ones. Usually you'll be writing some procedural code in IO,
             | or working with a parser, and realize "I'm writing a lot of
             | code checking for errors", "I'm tired of explicitly passing
             | this same argument", or "I need some temporary mutable
             | storage", or some other Effect - so you wrap up the Monad
             | you're using with a Monad Transformer like `ExceptT`,
             | `ReaderT`, or `StateT` in a `newtype`, derive a bunch of
             | typeclasses, and then just delete a bunch of messy code.
        
             | yodsanklai wrote:
             | > should I implement the Monad, Applicative or Functor type
             | class?
             | 
             | You rarely have to implement these type classes. But you
             | need to understand how they work since many libraries use
             | them. If you do IO, error handling, concurrency, use
             | containers, option parsing and so on, you'll have to use
             | these type classes.
             | 
             | For your own types, nobody forces you to implement them. If
             | it turns you can make your type an instance of some type
             | class, you may be able to reuse existing code rather than
             | reimplementing it. And it will make the program more
             | readable too.
        
           | jaspervdj wrote:
           | This talk seems like exactly what you are looking for for:
           | 
           | Gabriel Gonzalez - "A bare-bones Twitter clone implemented
           | with Haskell + Nix" @ ZuriHac 2020
           | https://www.youtube.com/live/Q3qjTVcU9cg
        
           | ngruhn wrote:
           | Highly recommend Richard Eisenbergs video series on building
           | a Wordle solver https://youtube.com/playlist?list=PLyzwHTVJlR
           | c9Fcinmxe97pHl_...
        
         | globnomulous wrote:
         | I'm not familiar with Haskell and am really, really struggling
         | to follow the article.
         | 
         | In the case of the functor, the author doesn't explain in
         | technical, specific enough terms the difference between "open
         | the box, extract the value out of it, apply the function, and
         | put the result back in a box" and "apply a function to a box
         | directly; no need to perform all the steps ourselves." I have
         | no idea what 'apply a function to a box' even means.
         | 
         | > That's the essence of functors: an abstraction representing
         | something to which we can apply a function to the value(s)
         | inside
         | 
         | The error in this sentence garbles its meaning beyond recovery.
         | "We can apply a function" governs two prepositional phrases
         | that are semantically and syntactically identical: "to which;"
         | "to the value(s) inside." There's no way to resolve the meaning
         | of one without rendering the other incoherent.
        
           | BoiledCabbage wrote:
           | The number one mistake is everyone trying to explain a
           | Haskell concept to the general population makes is using
           | Haskell. If someone already knows Haskell there is a good
           | chance they know there concepts. Don't use Haskell as the
           | language, use js to explain it.
           | 
           | The number two mistake people make is being aware of the
           | number one mistake so they go write yet another Monad
           | tutorial in Javascript (or Java or whatever...). Which is why
           | there are so many damn Monad tutorials, all saying pretty
           | much the same thing.
        
             | timeon wrote:
             | > The number two mistake people make is being aware of the
             | number one mistake so they go write yet another Monad
             | tutorial in Javascript (or Java or whatever...). Which is
             | why there are so many damn Monad tutorials, all saying
             | pretty much the same thing.
             | 
             | I was lucky seeing this before hitting submit button. Phew
             | that was close.
        
               | BoiledCabbage wrote:
               | Glad I could help you out there.
        
         | alabastervlog wrote:
         | Every "hard" concepts I've seen in Haskell is immediately clear
         | to me if explained in almost any other language. The hard part
         | is Haskell, not the concept.
         | 
         | Usually I'm left wondering why whatever-it-is even has a name,
         | it's so simple and obvious and also not that special or useful
         | seeming, it'd never have occurred to me to name it. I guess the
         | people giving them names are coming at them from a very
         | different perspective.
         | 
         | Exception: type classes. Those are nice and do need a name.
        
       | rebeccaskinner wrote:
       | I think it's great that people are excited about Haskell and want
       | to write about it, and it's unfortunate that the author had to
       | deal with a less thank tactful response to their work. I hope the
       | author keeps spending time with Haskell and continues to make
       | time to try to write more and help other people!
       | 
       | That said, here is a bit of a long comment on my thoughts about
       | writing about and teaching these things:
       | 
       | It's true that teaching Monads, Applicatives, and Functors can be
       | tricky and there are a lot of articles that end up doing more
       | harm than good- either by teaching things that are outright
       | incorrect, or more often, teaching people a particular way to use
       | them but setting people up for a lot of trouble when they run
       | across uses that diverge significantly from the mental model
       | they've built up.
       | 
       | Functions are a classic example of this. There useful definitions
       | of Functor, Applicative, and Monad for functions, and depending
       | on the mental model you've built up they can be either fairly
       | easy to understand or very difficult to understand. This ends up
       | being a big problem because Applicative and Monadic functions are
       | so pervasive, but they are incomprehensible if your stuck in the
       | traditional data structure mental model. IO is a great example of
       | this- it's really just a specialized State, but it can be really
       | hard to understand how it works if you're thinking about data
       | structures. Parsers are another good example.
       | 
       | I generally prefer to start people off with the "monad-as-
       | computation" mental model, roughly "An `m a` is an m-computation
       | that can have side effects and when evaluated returns a value of
       | type a", where Maybe are computations that could fail, Lists are
       | computations that can return multiple times, and IO are
       | computations with all of the normal IO side effects.
       | 
       | Starting with IO has the nice benefit that you can also help
       | people come to terms with monadic IO as a means of dealing with
       | lazy evaluation. It's a good gateway both into helping people
       | come to terms with the challenges of lazy IO, and it also helps
       | to provide a concrete motivation for IO in haskell that doesn't
       | result in people going off thinking that Monads are a hammer and
       | every problem in the world is a nail.
       | 
       | From there, I think it's helpful to talk not just about bind but
       | also join. Showing someone how to implement join in terms of bind
       | and vice versa is a nice thing to do early because it helps to
       | differentiate Monad from Applicative and it demystifies the "a
       | monad is a monoid in the category of endofunctors" thing a bit
       | (not that I'd proactively bring that up when teaching someone how
       | to use them).
       | 
       | I like to characterize the high level difference as something
       | like "Monads are computations that can _call out to_ other
       | computations and integrate their results", "Applicatives can run
       | computations in parallel and combine the resulting structures /
       | side effects", and "Functors allow you to lift pure functions
       | into a computation". At each step, highlighting both how you are
       | getting less powerful (because you can implement functors in
       | terms of applicatives, and applicatives in terms of monads, but
       | not the other way around), and how having less power can help you
       | reason better about your programs (pros/cons of applicative vs.
       | monadic parsers are a good example here).
       | 
       | Finally, I think it's important early on to make sure your reader
       | understands higher kinded types. A lot of people are used to
       | languages with generics, but many of those languages aren't
       | expressive enough to let you express something like Functor, and
       | people often lack practice in thinking about something like
       | `Maybe` separately from `Maybe Int` or `Maybe a`.
       | 
       | In the end, I think these things really aren't that complicated,
       | but they are built on a different view of programming that a lot
       | of readers have the first time they encounter them, and the best
       | approach isn't to translate the concepts into something people
       | are already familiar with. Instead, I think you need to help the
       | reader adapt their mental model. It's a harder path, but one that
       | I think pays off more in the long run.
        
       | IshKebab wrote:
       | The problem with Monads etc. is that they're simple concepts with
       | extremely confusing names. Monad should be FlatMappable. Once it
       | has the correct name it barely even needs an explanation at all.
        
         | agumonkey wrote:
         | Even though I see why it could help as introduction, I think
         | flatmap is too narrow to express monadism
        
         | bontaq wrote:
         | I've seen this opinion before but disagree with it. There are
         | maybe five names to learn. They relate to the actual concepts,
         | allowing you to expand your knowledge.
        
         | contravariant wrote:
         | One issue with that is that you can write Flatmap in a way that
         | doesn't obey the Monad axioms. And once you write out what it
         | means to be 'correctly' flatmappable you've recreated the Monad
         | axioms.
         | 
         | Though it would help if more people were aware that a 'nice'
         | way to 'unnest' a functor (F F x -> F x) is really all that it
         | takes to have a Monad.
        
         | yodsanklai wrote:
         | FlatMappable doesn't capture what a monad is. For instance, you
         | can do async programming using monads. Doesn't relate to
         | FlatMappable.
         | 
         | I think you don't see the need for a new name if you don't
         | grasp the concept. It's like in mathematics, you have tons of
         | algebraic structures, like monoid, groups, fields, rings. They
         | all represent categories of things which share some properties.
         | You don't want to name the category by a one of its
         | representatives, that would defeat the purpose of introducing
         | an abstraction.
        
       | e-dant wrote:
       | Part of why monads are not interesting to talk about is that
       | they're generic enough that most explanations are incomplete, and
       | sufficient explanations are boring and unhelpful.
       | 
       | But the biggest reason is that they're sort of intuitive, plenty
       | examples exist. And then at some point someone tells you that
       | those things are monads, but it's in the kind of way that social
       | psychologists make up some fancy word for crap we all _know_
       | about in our gut.
       | 
       | Nobody gives a shit that a list is a monad, people give a shit
       | that it's a list. Anyone who's written lisp or node or any
       | nontrivial C program or anything with coroutines or anything with
       | concurrency can and _will_ tell you that, yeah, duh, control flow
       | can be represented by a data structure. A couple more fancy
       | "monad laws" and you have something that looks like other monads,
       | and lists and if expressions and IO meld together. Ok, how
       | unhelpful.
        
         | chowells wrote:
         | The helpful part is the ability to abstract over arbitrary
         | monads. That's the thing that makes it worth identifying that
         | it's a known and well-studied pattern.
        
         | hibikir wrote:
         | The fact that they are so generic is what makes people
         | misunderstand them: They focus on 1 or 2 examples, without
         | seeing that the same concept works in all kinds of other use
         | cases.
         | 
         | People realize a list can be a monad, and they they imagine
         | option and set are also monads. But then you have to tell them
         | that the same applies to Future, and Either. That you can have
         | a resource monad that closes resources.
         | 
         | This is when the fact that something is a monad starts to
         | matter, because of generic concepts for transformers. Every
         | language that has promises and lists will give you a way to
         | turn a List[Promise[T]] into Promise[List[T]], written ad-hoc,
         | but it doesn't have to be quite so ad-hoc. It's when you are
         | stacking 3 or 4 different properties together that the abstract
         | concepts matter. The lack of the abstraction is what makes some
         | language have trouble doing more than just a little bit of
         | functional programming, as going deeper becomes unmanageable
         | without some help.
        
         | VirusNewbie wrote:
         | But if people understood monads they wouldn't be bending over
         | backwards to shoehorn specific syntactic sugar just for _error
         | handling_.
        
       | hu3 wrote:
       | This is how Chat GPT o1 would explain Functors, Applicatives and
       | Monads to a PHP developer. Looks more digestible to me, supposing
       | it is correct.
       | 
       | https://chatgpt.com/share/67e9b3b0-52a8-8001-87d1-d6d222a27e...
       | 
       | The prompt to save you a click: "I'm an experienced PHP
       | developer, explain Monads to me using PHP exmaples." (yes I made
       | a typo in exmaples but it worked fine anyway).
        
       | layer8 wrote:
       | > A functor is an abstraction that allows for mapping a function
       | over values inside a context without altering the context of the
       | functor.
       | 
       | I'm not sure this is intelligible to laypeople. ;)
        
       ___________________________________________________________________
       (page generated 2025-03-30 23:00 UTC)