9 ms·
An Overview of the Monad
- the_af 7y agoThis isn't an useful article about monads in my opinion. It adds neither insight nor depth, is completely redundant given the hundreds of articles out there, and is unlikely to give anyone struggling with monads an insight that would help them. Particularly egregious is the fact it introduces a formal definition only to immediately ditch it because it's "probably pretty incomprehensible" -- and this in 2-minute read with no room to spare. Besides, everybody knows monads are not like containers. They are like burritos! https://blog.plover.com/prog/burritos.html https://blog.plover.com/prog/burritos.html
- cousin_it 7y ago> we can think of a monad as a datatype with Aaaaaaa Be more precise about instance relations! They are the first source of confusion! - String is a type. The value "abcde" is an instance of that type. - Num is a typeclass. The type Int is an instance of that typeclass. The value 12345 is an instance of that type. - Monad is a typeclass whose instances are generic types. The generic type List is an instance of that typeclass. The type List Int is an instance of that generic type. The value [1,2,3] is an instance of that type. Explaining the operations of Monad is only useful when you're comfortable with "value belongs to type which belongs to generic type which belongs to typeclass".
- patrickthebold 7y agoAnd if you think about it, you're just asking the author to be clear about the types of the things they are talking about.
- jhanschoo 7y agoIs there really a need to distinguish between types and typeclasses though? You can have a notion of type and inheritance where Monad is a type, and Lists, Promises, Option, etc. are subtypes of Monad.
- selbekk 7y agoI've always struggled to grok the concept of monads. Worth the 2 minute read.
- mbrock 7y agoAnother way to say it: a monad is a generic type with the sufficient API to do binding sequences like x <- fetch "foo" y <- frob x return (x + y) The meaning of binding/sequencing is decided by the particular monad instance. This is why it's a useful formalism to represent things like asynchronous I/O (you make the sequencing mean promise chaining), abortable computations (you make the sequencing cancel when it sees failure values), combinatorial/nondeterministic programming (you make it so one binding can happen several times). Monads are also closely related to continuation-passing style or delimited continuation capture, and those techniques can also be used to implement everything monads can.
- tylerhou 7y agoExcept this “simple” metaphor isn’t too useful. For monads like IO and State, “monad as a container” is a stretch. And some don’t fit at all — the list monad often is imagined as a computational context with nondeterminism, not simply a container. https://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/ https://byorgey.wordpress.com/2009/01/12/abstraction-intuiti...
- mikekchar 7y agoI don't really understand your point of view. Especially the list monad is literally a list. The shape of bind for the list monad is [a] -> (a -> [b]) -> [b]. If that's not a container, I don't know what is. The fact that it can be used to solve problems where the list represents a non-deterministic result is really secondary. I mean, I suppose you can think of it as being different, but it seems a lot more complicated in my mind. I think some "containers" a definitely hard to envision. A partially applied function is also a monad (i.e. it's trivial to write a meaningful bind for it). It may be hard to think of a partially applied function as "containing" the applied parameters, but I still think that's easier than any other way of envisioning it. But maybe it's a matter of horses for courses.
- antonyh 7y agoThat has to be the most cryptic explanation but then again perhaps I need the ELI5 version. I’m certainly none the wiser for reading it.
- steven741 7y agoThis was a little sparse but it was a fun read.
- skrunch 7y agoThe visualisation linked to at the end goes into some more detail and was definitely worth the extra 5 minute read for me!
- bobmichael 7y agoI found the article the author links to, which explains functors, applicatives, and monads in pictures, to be way more helpful: http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html http://adit.io/posts/2013-04-17-functors,_applicatives,_and_...
- itronitron 7y agoYeah, interesting to learn that a monad is a value in a box, almost as if it were an object
- the_af 7y agoThe problem is, of course, that a monad is not a value in a box. That's a misunderstanding, resulting from an oversimplified metaphor. This shows a frequent problem with metaphors. See "the fallacy of monad tutorials": https://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/ https://byorgey.wordpress.com/2009/01/12/abstraction-intuiti...
- chongli 7y agoIt isn’t though. A monad is just an abstract mathematical object that satisfies a few axioms. It doesn’t have anything to do with implementations or computations, let alone objects in the OOP sense. It’s better to think of it like this: a value in a box is one example of a data type that can satisfy the monad axioms. Another example is a delayed computation that produces a value when executed. Yet another is a delayed computation which produces no value at all but causes a message to be printed to the screen.
- simendsjo 7y agoBartosz Milewskis Category Theory for Programmers also has nice explanations for all these concepts. Haven't read through everything, but what I've read has been very high quality. https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/ https://bartoszmilewski.com/2014/10/28/category-theory-for-p...
- classified 7y agoMilewski's explanations are among the best of what you can find on the net. Much better than OP anyway.
- phs 7y agoHis video lecture series is also well-paced. https://www.youtube.com/user/DrBartosz/videos https://www.youtube.com/user/DrBartosz/videos
- goto11 7y ago> We simply cannot think about such abstract concepts without introducing some sort of metaphor. Metaphors are overrated. Often they obscures more than they explain, especially for such an abstract concept. What if you had to explain "statements" with a metaphor? Or "expression"? I challenge anyone to come up with metaphors which help more than they confuse. We learn programming concepts through examples, and seeing how they are useful. Not through metaphors.
- maweki 7y agoBut usually nobody cares about or checks whether your implementation of the operator your overriding still obeys all the axioms. Sometimes we have tests whether some interface implementation fulfills some axioms, but usually we do not. Somehow with monads we do. And I suspect the reason is, that monads come from an area where of Programming where proving a program correct is preferred to testing. And for proving correctness, you need a proper specification and then implementations that follow that specification. And a specification is done using abstract concepts. If you want to prove anything about your program (or even understand obscure edge cases), concepts through examples will not work for you.
- marcosdumay 7y ago> But usually nobody cares about or checks whether your implementation of the operator your overriding still obeys all the axioms. Make some non-associative implementation of (+) and see on how many compilers code using it will work.
- Tainnor 7y agoMetaphors are a very powerful tool in human cognition, and there has been a lot of research into their usage from a cognitive science perspective (see e.g. the works by George Lakoff). Of course, an abstract mathematical proof is independent of any metaphors you may ascribe to them, but new maths is usually discovered by applying intuition to a problem and then verifying that the intuition is in fact correct. To do that, you need metaphors and analogies. The interesting part is when you can use several metaphors for the same concept and the key insight comes from a shift in perspective; e.g. some statements about complex numbers make more sense when viewed from a geometric (rotation-inspired) perspective. Similarly, thinking about e.g. monads as "containers that can be flattened" can lead to certain insights, but thinking about them in some other ways can maybe lead to different insights. However, I agree with you in one point: we learn mathematics and programming by example; I think the key point is that people have to build their own intuitions and metaphors. It can be useful to guide people along that path, e.g. by pointing out some helpful analogies or dismissing some unhelpful ones, but ultimately, you have to start working with the concept and prove/disprove your own assumptions (this is as true of a new programming concept you're not familiar with yet as of mathematics, only that in the former case you're much less formal about it).
- Rerarom 7y agoMy problem with understanding monads was as follows: I had no problem with understanding the mathematical definition, it was easy to check that a given monad verifies the axioms. No, my problem was this one: everyone was saying "hey, you know if you have a purely functional language, it would be impossible to have IO, since e.g. a read function would have different outputs every time. We solve that with monads." But that didn't feel like an explanation. I couldn't draw a line from the monad axioms to dissolving that impossibility. It was like saying "Einstein says we can't do FTL, but we can solve that with monads".
- deleted 7y ago[deleted]
- goto11 7y agoThe solution is not really depending on monads. You pass "the world" as a parameter to read. If you pass a different world, you will get a different output. All function which interact with the world get a "world" parameter and returns a new modified "world". So now all IO operations are pure! Monads are used as a trick to hide the "world" argument, so you can't cheat by e.g by reusing the same world twice. Maybe something like ownership in Rust could be used for the same effect?
- ourlordcaffeine 7y agoI thought Monads were needed for IO to make sure IO operations happened in the correct order?
- theaeolist 7y agoYes, this is the correct answer. For everything else you don't need monads. Monads impose an evaluation order, which Haskell by default does not have, since it is lazy.
- gmfawcett 7y agoMonads do not impose an evaluation order in Haskell. Monads let you thread state between computations, but that state may be lazily evaluated out-of-order. The belief that monads sequence IO operations is why new Haskell programmers have difficulty writing functions like "open file, read file contents, close file, and return contents". They assume the contents will be read before the file closes, and not when the contents are lazily evaluated up the call chain (leading to a "can't read closed file" error).
- sullyj3 7y agohttps://xtendo.org/monad https://xtendo.org/monad This is the best introduction to the topic I've seen for Haskell beginners. It provides some much needed context.
- classified 7y agoThat's a great presentation that every Haskell beginner should see. As an extra it has some insights on the failure modes of (monad) tutorials, like "Using things you don't know in order to teach you something you don't know".
- harry8 7y agoOh for the day when monad tutorials and explanations don't outnumber useful Haskell programs with a purpose other than programming a computer by many orders of magnitude. The list of such programs hasn't grown much since the last time I noticed that we did this 2-3 years ago has it? Git annexe, ion, pandoc, and..? There were a couple more than that, i think.
- Peter_Storm 7y agoAre you talking useful for us as developers, or Haskell being used in production? Because there are plenty of examples of Haskell being used in production.
- swebs 7y agoI think Xmonad is the biggest one.
- drngdds 7y agoThere's more Haskell-based software out there than the stuff that's open source or advertised as being Made With Haskell
- np_tedious 7y agoPostgrest is a pretty cool one. And arguably Elm could be included. That's getting more widely used
- goto11 7y ago“There are only two kinds of languages: the ones people complain about and the ones nobody uses.” Except for Haskell which happens to be both!
- darkkindness 7y agoI always see monad tutorials like this conflate (1) "understanding using particular monads" with (2) "understanding using monads in general", which are completely different things. Luckily it's easy to not confuse those two with (3) "understanding monads abstractly" which tends to break out the category theory, but some tutorials like jumping on that too. To demonstrate the differences, suppose now that you're deep diving into a codebase which depends on a Async monad. Your eyes light up and you go aha(!) that means async programming, I've done that before! The point is, you saw "Async", you know it means "make some task's outcome depend on a previous task", which is the behavior of bind for that particular monad. Without (1) the word "monad" is really unnecessary. Why not just refer to bind as some arbitrary async-API function? In summary, you don't need (1), (2), or (3) for this! Monad is just a word. Okay, when do we need (1)? Let's say you've changed companies, and now you're plugged into another codebase and oh(!) there's that word "monad" again, but this time it's the "Future" monad. Another whole API to learn... but soon you realize that it's again the same old "make some task's outcome depend on a previous task". Except they just call it "Future", and instead of "bind", they say "flatMap" which is the same thing! And you bump into it again and again with different names -- Deferred, Aff, Task -- but in the end it's the same behavior and API. How upsetting that they don't call them all Async and be done with it! But if you have (1) you'll know they are just the same monad, given different names. That's (1): familiarity with the usage of a particular monad. Later on you might collect understanding of the Option/Maybe/Nullable monad, or the Result/Either/Error monad, or the List/Stream/Nondeterministic monad, so now names don't bother you because you know CONCEPTS, but all of this is still (1) if each monad is being treated as an independent API to grok. That's where (2) comes in. Suppose now that you're deep diving into a codebase which depends on the "Anisotrope" monad. You've never heard of this before[0], but you know monads in general i.e. (2), so you know you can make functions whose output (an Ansiotrope object) depends on some property of a Ansiotrope object, and that all the details about this dependency can be found in the definition of bind for this particular monad. In other words you can use knowledge of (2) to quickly adapt to new monads without having to regard them as a completely new concept. It lets you answer questions like "what's this Probability monad supposed to do? what about this Forkable monad?" in a general way. Conversely, you can now start writing monads of your own by thinking about what bind could mean for your new "Transmogrifying" monad. Is this useful? Imagine learning all OOP patterns knowing that every pattern is the same concept except for this one thing: bind. That means it's relatively trivial to learn these patterns and make new ones. Except they're not OOP patterns, it's monads, and no, you can't generalize OOP patterns the same way. Anyways, this is also where "monad is a box"-esque metaphors fall short. It's rather descriptive of particular monads, but doesn't generalize well when you start reaching for many others: Reader(environment-passing), List(nondeterministic computations), Probability(probabilistic programming), or fun ones like parser monads, Amb(backtracking), Tardis(state-access-timeline-specifying)[1]. [0] I hope not, since I made it up. If you have (3) you're probably deriving a working definition already. Have fun! [1] http://hackage.haskell.org/package/tardis-0.4.1.0/docs/Control-Monad-Tardis.html http://hackage.haskell.org/package/tardis-0.4.1.0/docs/Contr...
- mbdesign 7y agoDidn't even know there existed a .christmas domain.
- classified 7y agoOnly accessible while Santa Claus is visible in the night sky.
- classified 7y agoWell, that was quick. For the umpteenth entry in the class of utterly useless and incomprehensible "monad tutorials", this one is at least short.
- ashton314 7y agoThis was the first time I've seen the "A monad over a category C is a triple (T,η,µ)" in a definition. That confirmed some mental models that I was a little unsure about. I'm new to the fp scene; still trying to get a good foundational understanding.
- TheAsprngHacker 7y agoIf you're new to functional programming, you don't need to worry about the category theory definition. Especially since this tutorial simply mentions it as a way to say, "this is too complicated for us, so we're going to explain it another way," and makes no attempt to break down the definition as code. In fact, be careful that you're not seeing category theory definition and misunderstanding it to confirm a mistaken intuition. The category-theoretic definition basically states that a monad is an endofunctor T equipped with two operations, return :: a -> T a and join :: T (T a) -> T a. T being a endofunctor just means that it is "mappable," AKA it has a function fmap :: (a -> b) -> T a -> T b that "lifts" functions into the type. Monads capture the idea of flattening. If fmap changes the "contents" while preserving the "shape," join collapses nested layers to change the "shape." Instead of join, the Haskell typeclasses (and this article) uses another function called bind, or >>=. You can derive join from >>=, and you can derive >>= from join and fmap. For lists, a more familiar name for >>= might be flatmap.
- deleted 7y ago[deleted]
- mikorym 7y ago> A monad is a concept that belongs to a branch of mathematics called category theory, where it was introduced in the 1960s. No. [1] [1] General Theory of Natural Equivalences, Mac Lane and Eilenberg, 1945. https://www.ams.org/journals/tran/1945-058-00/S0002-9947-1945-0013131-6/S0002-9947-1945-0013131-6.pdf https://www.ams.org/journals/tran/1945-058-00/S0002-9947-194...
- mikorym 7y agoSorry, I misread; monads were only introduced later. The above paper introduced the field of category theory itself.
- jcmontx 7y agoTIL that the domain extension ".christmas" exists. I wonder why though...
- WorldMaker 7y agoCapitalism
- the_af 7y agoHere's an interesting article about the "Fallacy of Monad Tutorials" and why most metaphors fail: https://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/ https://byorgey.wordpress.com/2009/01/12/abstraction-intuiti... The key insight here is: there are no shortcuts. Most metaphors are useful but limited. Once a metaphor "clicks" for a person, they forget all the work it took them for the concept to really click, and think the shortcut will help other people: "Monads are like burritos! If only other people understood this, they would get them!". > "But now Joe goes and writes a monad tutorial called “Monads are Burritos,” under the well-intentioned but mistaken assumption that if other people read his magical insight, learning about monads will be a snap for them. “Monads are easy,” Joe writes. “Think of them as burritos.” Joe hides all the actual details about types and such because those are scary, and people will learn better if they can avoid all that difficult and confusing stuff. Of course, exactly the opposite is true, and all Joe has done is make it harder for people to learn about monads, because now they have to spend a week thinking that monads are burritos and getting utterly confused, and then a week trying to forget about the burrito analogy, before they can actually get down to the business of learning about monads." Already in this comments section I see this kind of misunderstandings: "monads are containers with values in them, almost like objects", "monads are for effectful computations", "monads are for imposing a sequential order", etc. These are all particular uses of monads, but not what monads are.
- BoiledCabbage 7y agoI'll post this again "If you are interested in learning functional programming do not learn about monads". There is no practical justifiable reason to learn about monads unless you already know Haskell. And there is no reason to learn Haskell unless you already know another statically typed functional language. If you are interested in learning functional programming then either Learn dynamically typed functional programming and pick Clojure (or Racket). Or learn statically typed functional programming and learn Elm then F# (or OCaml). Haskell is the worst language you could choose to learn FP. If you're trying to lean FP, stay away from it. If you're a huge FP advocate don't push it. And finally monads tutorials are the white noise at the end of a wrong way track in learning about functional programming. Outside of Haskell, monads are about as important in terms of learning, knowing and effectively using functional programming languages and concepts, as braces being on the same line or next line is important to learning about general programming. It's not. Does that mean no-one can ever mention a monads, no of course not. But it's such a tiny topic, that it's absurd it gets so much discussion like it's some key to learning fp or some incredibly crucial concept. It's not.
- TheAsprngHacker 7y agoI use OCaml, and monads also come up in OCaml code. Monads may not be as essential to understand in OCaml than in Haskell because OCaml doesn't use them to track IO in the type system, but people use them in OCaml to chain options and results. In fact, OCaml 4.08 introduced syntactic sugar that makes functor, applicative, monad usage more convenient. I'd say that monads are something that non-Haskell functional programmers should learn. Monads also turn up with lists (flatmapping) and promises. Although you don't need to know what a monad is to flatmap a list or use promises, I'd say that being aware that lists have a monad instance or that promises have a monad instance provides insight.
- jolmg 7y ago> Haskell is the worst language you could choose to learn FP. Why?
- BoiledCabbage 7y ago
- AzzieElbab 7y agoA monad certainly is not a container. None of the functional patterns are containers.
- tutfbhuf 7y agoI think in order to understand Monads you should try to invent them yourself. Try to create a pure IO function in the programming language you know best. Consider the state of the world as input parameter of your function and return a modified version of the worlds state. Then try to compose IO functions and try to write an interface for IO function composition.