10 ms·
Monads are a class of hard drugs
- bluepoint 4y ago> The essence of monads is to use abstract types to enclose a mutable state, providing only a set of carefully-crafted combinators for using it in such a way that you can't duplicate the state but have to use it in a linear, non-branching fashion When I was reading about these stuff, I was not lucky enough to find such a clear high level description of what is the purpose of a monad. I got it eventually, but I wish I encountered this concise description earlier.
- tromp 4y agoIt's a rather incomplete description of monads, since besides "mutable state", monads also cover optional state (Maybe), multiple states (List), dependent state (Reader), exceptional state, etcetera.
- platz 4y ago> you can't duplicate the state but have to use it in a linear, non-branching fashion So so you're saying bitcoin should have been made out of monads?
- Koshkin 4y agoI suspect that it is only after you ‘got it’ that you can find this description nicer than anything else that you can find in the swath of monad tutorials.
- jerf 4y agoUnfortunately, if this is your understanding of monad, that is itself proof that you did not "get it". It is neither required for mutable state, nor required for mutable state in Haskell, nor are all monad implementations about mutability. That is, that understanding is neither a subset of understanding monads, nor is a proper understanding of monads a subset of thinking of them as being about mutability. It's just wrong, unfortunately. I wrote about this extensively in http://www.jerf.org/iri/post/2958 http://www.jerf.org/iri/post/2958, "Functors and Monads For People Who Have Read Too Many 'Tutorials'". If original post is from 2008, then it is the sort of "too many 'tutorials'" that you may have read about them.
- sudosysgen 4y agoSure, the idea that they have to be mutable in practice is incorrect, but Haskell has "do notation" which makes Monads act as if they always introduced mutability, and in the spirit of a simplification it is correct in the essence. The essence of the understanding that Monads act as a wrapper and define lifting and composition of wrapped types is correct in essence and that's the meat of the understanding. Define it a bit more rigorously and it's literally mathematically équivalent to saying "monoid over the category of endofunctors".
- nightski 4y agoNo. Do notation has nothing to do with mutability. Do notation is a convenient syntax for monads period. You can use it with the list monad for example and not IO at all.
- sudosysgen 4y agoDo notation gives the syntax and almost the semantics of mutability. I never said it actually means they are mutable, just that it is practically as if they were. Which is what the author says about Monads, they mean that practically it's as if they were mutable. And yes, that goes with the list monad too when using do notation. It's syntactically and in practice almost as if you were mutating a new list and then returning it.
- nightski 4y agoI don't agree. Maybe let's use a different example to illustrate more clearly - the maybe monad. Let's pretend you have a series of functions a, b, and c which take a value of type X and return a value of type Maybe X. With do notation you can chain the functions like this - do r1 <- a 1 r2 <- b r1 r3 <- c r2 r3 This is about composing functions. It has nothing to do with mutability. It is just a convenient way to write the composition rather than using nested bind operators.
- 4y ago
- cuteboy19 4y agonow that you have understood it, it is your duty to write yet another monad tutorial
- mrkeen 4y ago> The essence of monads is to use abstract types to enclose a mutable state, providing only a set of carefully-crafted combinators for using it in such a way that you can't duplicate the state but have to use it in a linear, non-branching fashion This is a good description of one particular monad, the ST monad: https://wiki.haskell.org/Monad/ST https://wiki.haskell.org/Monad/ST
- sudosysgen 4y agoThe ST monad is a good example, but that's the basic pattern of the Monad. Lifting a base type into a monadic type and composing monadic functions.
- mrkeen 4y agoI may not have been harsh enough. The ST monad (enclosing mutable state to use it in a linear, non-branching fashion) is indeed a good example of a monad. Calling that the essence of monads is as accurate and helpful as calling it a burrito [1]. Future downvoters may want to try to reconcile any of the other common monads (Maybe, Either, List, State, Parser, Reader, Writer) against this enclosed/mutable/linear/non-branching definition and see if the essence fits. [1] https://kjaer.io/a-monad-is-not-a-burrito/ https://kjaer.io/a-monad-is-not-a-burrito/
- sudosysgen 4y agoI have considered all of those Monads and more when assessing that definition. The Maybe monad is in essence a Boolean wrapped around the base type (for which a value may be null but is part of the monoidal type nonetheless). The Either monad is another Boolean wrapped around the union of two types which itself a type. In all cases an operation on an object of the monoidal type will mutate the wrapper type but not the wrapped type which always stays the same. The List monad is even simpler, it's a linked list, so the wrapper contains another successor list which may be empty but of the same type and a value of the current type with mapping being an operation that maps function in the base type into functions on the monoidal type. The State monad is obvious. The Parser monad typically wraps around some form of string which is partially parsed and then contains an element or a list thereof of the parsed type such that operations on the string type yield a partial parse. The Reader and Writer Monads are obvious. This type of intuition always works on Monads. If you want to learn more about it I'd recommend to learn about the relationship between the Kleisli Triple and the monad. In reality this way of understanding this is just an intuition of how the Kleisli Triple works and how it is an equivalent to the traditional representation of the monad.
- pyrale 4y agoIt's also wrong. Lists are monads, and whether the implementation you use is mutable or not is not relevant to how you use them. The essence of monads is not about what use can be made of them either, just like the essence of things that have a hook is not that you can use them to hang your coat. Simply put, monads are data types that share a set of properties. Think of them as you would think of the atoms that are halogens, or of the animals that are mammal. In the case of monads, the property is that functions can be chained on them in a specific way, and that the result of this chaining respects some rules. The reason it is so hard to explain or understand monads is that this property in many different ways for many different ends, and that the what and the why are often mixed in the explanation.
- deleted 4y ago[deleted]
- quelltext 4y ago> Lists are monads Isn't it just that you can define monadic interfaces for lists, as you can with (probably all) parametric data types? Saying "the list monad" wouldn't be correct, right? Although it's pretty common to see that phrase.
- jerf 4y agoMonad is just an interface; all "monad"s are things that declare some function that conforms to the interface. You can say "the list monad" reasonably because there is only one sensible implementation of (List a -> (a -> List b) -> List b) in Haskell. You could unconditionally return an empty List b and fulfill that interface, but what would be the point of that? You can't just return a list of all the things the function call resulted in because that would be a List of a List of b, which is not the same as a List of b. You can't sort them in Haskell because you don't have any form of comparability available in that interface specification. etc. Technically in other languages this may be less true as due to having fewer restrictions (for example, you may in a language that defines ordering on all values, and thus you could sort the result regardless of the types involved) you can do more things, but there's still really only one sensible and unsurprising implementation.
- imtringued 4y agoI disagree with the description though, a monad is effectively the hot cell of functional programming. You aren't allowed to touch the contents of the hot cell, instead you must send a robot arm into the hot cell. What is surprising though, is that the robot constructs another hot cell inside the hot cell and then merges it with the outer hot cell The problem with monad is that it is a typeclass with not much meat on it, it would be more appropriate to talk about monad instances.
- feet 4y agoThe term 'hard drug' is meaningless and has no real definition in the field of pharmacology. We need to stop using it.
- ajkjk 4y agoIt's perfectly meaningful, as the meaning is clear to the reader.
- feet 4y agoGreat, so are we using phrases and words that people define wildly differently to describe specific things? That's a terrible way to go about communicating ideas. As a pharmacologist, the phrase is meaningless to me. There is literally no distinction between 'hard' or 'soft' drugs
- mckirk 4y agoIs it really meaningless? Despite how fuzzy the exact boundaries might be defined, I think it would be pretty safe to assume weed would be in the 'soft' category, and crack in the 'hard' category.
- feet 4y agoIt absolutely is meaningless. Why would I assume that cannabinoids are 'soft' and cocaine base is 'hard'? Apart from the fact that the word 'hard' is literal slang for crack while 'soft' is slang for powder cocaine in the salt form The terms are meaningless to me, I have no reasonable way of classifying anything into those categories because the categories literally have no meaning
- corrral 4y ago> As a pharmacologist, the phrase is meaningless to me. Glad I'm not a pharmacologist, so I can understand the term in this context.
- 4y ago
- platz 4y ago[2008]
- neals 4y agoSo monads are from functional programming, right? 10 years or so ago they were all the hype on here. I tried to follow so many Youtube (and written) tutorials on Monads, but I never understood. Maybe I should try again not that I'm a bit older and more experienced...
- jodersky 4y agoI usually tell people that monads are an abstraction which encourage writing code with less branches. Consider the following code where you would like to multiply a number by two, but this number is potentially undefined: var x = ... // a number or null if (x == null) return null else return x * 2 Now, imagine if x were a list containing zero or one numbers (if the number is undefined, the list is empty). In this case, you could refactor the code as follows: var xs = ... // a list of zero or one numbers return xs.map(x => x * 2) The advantage of the second snippet is that there are no branches, thus making it easier to reason about the code. Thus, in order to understand 80% of their utility in 20% time, I can recommend that you think of a monad as a wrapper around a value which allows you to treat special cases uniformly. In this case, a list of one or zero items. Of course there is more to it, but I this is usually enough to get people to stop worrying and interested in exploring more.
- yodsanklai 4y agoI think a prerequisite is to have some experience with functional programming (F#, OCaml, Scheme...) and then realise a simple option type implement a monadic interface (bind + return). From there, you can basically try to write functions which return an optional value using bind/return rather than pattern matching on Some/None. From there, it comes with practice and you can see how bind/return work for other things (notably concurrency). There's no need for any theory to use monads effectively. To me, the problem with Haskell is that you need monad from the beginning, whereas in OCaml, you can start using them when you're familiar with basic ML.
- corrral 4y agoTry a tutorial written in a language you understand well that does not routinely feature monads. IME the biggest hurdle is convincing yourself you've actually understood them, because they seem so mundane that it's weird they even have a name.
- jmillikin 4y agoIt's amazing that the concept of "monad" is so simple, and yet the author still got the interface mixed up with one particular implementation (mutable state). Monads are about sequencing. They are an interface to force applying functions in a particular order. This is why Haskell needs them -- in a language with only pure functions, there's no way to encode (for example) the order of 'print' statements directly, it has to be expressed in terms of combining functions. Consider the interface, expressed in a C-like syntax: interface Monad { template<A> from(value: A) => Self<A>; template<A, B> sequence(self: Self<A>, f: fn(A) => Self<B>) => Self<B>; } You can see that it forms a sort of one-way valve for functions from one value to another. Types you could implement that interface for: * Lists: `from` wraps the value in a size=1 list, and `sequence` becomes "apply the function to each value then concatenate the results". * Optional: `from` is the case of a value existing, and `sequence` is "if value exists then apply the function, else return None". * Sets: same as lists. But it's hard to write a blog post about an interface with only two functions, especially if you've already committed a thousand words to making it seem complicated.
- edflsafoiewq 4y agoMonads are not about sequencing. They don't force applying functions in an order, at least any more than regular function application does. Haskell does not need them, they're just an interface and don't add anything to a language you can't do without them. The order of print statements is encoded the same way the order of elements in a list is, it's part of the definition of the data type. The monad instance says IO (IO a) is "the same as" an IO a, so really any sequencing ability implied in IO (IO a) already pre-exists in IO a.
- nightski 4y agoIt can catch newcomers off guard. People think they write - do a x b x in Haskell and that means the same as a sequential program (a runs before b). But this is not necessarily the case. It does not imply an order. It will only do so if the statements are dependent on each other - do c <- a x b c
- travisgriggs 4y agoThis is pretty dated (2008). I am not a hard core functionalist. I get to work with the crap show of “multi-paradigm” languages, enjoying the the occasional list comprehension. I’ve never experienced a monad. I am curious how much of some of the side comments made in the paper are still relevant? The quips about slowness, etc. Are these things that have dramatically shifted in 14 years, or only incrementally improved?
- Smithalicious 4y agoAny discussion about what a monad is rapidly degenerates into an endless sequence of >it's simple, monads are like X >you are wrong, it's actually simple, monads are like Y >you are wrong, it's actually simple, monads are like Z &c
- frazbin 4y agohttps plz thx
- cannabis_sam 4y agoThis blogpost and a lot of comments in this thread (but absolutely not all) don’t seem to realize that monads are an abstraction over lots of different, but common programming constructs. - Read-only values (e.g. environment variable, configuration) - Write-only functions (e.g. logging, compiler output) - State (read-write-values) - Sum-types (e.g. Optionals/Maybe, Either/result) - Inductive lists - Arrays/vectors - Contexts (e.g IO, file handlers, database cursors, etc) - Functions - Sequenced operations - Continuations - Parallelization - Concurrency - Interpreters - Compilers - Combinations of all of the above (plus more) - And whole programs - (and a whole lot more) All of these can be built as monads, since it’s an extremely general abstraction. But when you try to attach the specifics of any of these constructs to your explanation/view/understanding of monads you will inevitably run into issues/contradictions with other things that are also monads. At its core, monads are just an interface with two (or three) functions: - unit/pure/return, which puts a value into a monad - bind (or map and join) which combines a value in a monad with a function from that value into the same monad (Plus some algebraic laws about how these functions behave when combined.) However, the technical simplicity of this interface does not make it easy to understand how and why it’s a useful abstraction over so many programming constructs. IMHO, the best way to get a grasp of this, is to actually use and play around with a bunch of of these constructs via these monadic functions. (I am also thoroughly convinced that you can ignore Category Theory if you are only interested in monads as they are used in programming.)