3 ms·
Because, that's nowhere near general enough to describe what monads can do, that is, your explanation is wrong because of its over-specificity. That's the probl
by bowsamic 3y ago
Because, that's nowhere near general enough to describe what monads can do, that is, your explanation is wrong because of its over-specificity. That's the problem with monads. They are an extremely general mathematical object, but the specific uses of them are wildly different. It's the exact same "problem" with functor and applicative.
It's like explaining a vector space using the analogy of arrows in space and then having to explain how sets of functions are also a vector space.
In mathematics you just have to stick with the general definition and a few examples, keeping in mind that those examples are specific. Most programmers are simply not used to thinking in that way. That's why it's "some form of voodoo".
Further, much like the definition of a vector space does not make it immediately obvious that functions can be vectors, it's not obvious from looking at the definition of a monad that it allows us to do sequential IO. That's why people think it's some sort of voodoo. You have to just accept that the example obeys the definition, the example doesn't fall out of the definition.
- supermatt 3y ago> Because, that's nowhere near general enough to describe what monads can do Totally disagree. You are effectively saying you cant define anything unless you include every case, which is clearly nonsense. > it's not obvious from looking at the definition of a monad that it allows us to do sequential IO The transform is "transform the wrapped properties into some IO call", and all transforms are explicitly sequential.
- bowsamic 3y ago> You are effectively saying you cant define anything unless you include every case, which is clearly nonsense. No I'm not. I will repeat what I said again: such things are defined by their general mathematical definition, and any analogy can only speak for certain subsets of examples of that definition. > The transform is "transform the wrapped properties into some IO call", and all transforms are explicitly sequential. How exactly does the mathematical definition of a monad say anything about "transforms"? I think you didn't actually read my comment.
- supermatt 3y ago> How exactly does the mathematical definition of a monad say anything about "transforms"? Im not sure that it does, but a "transform" as I mean it in my basic description is applying an operation to the "wrapped" properties.
- bowsamic 3y agoThe transformation mentioned there has nothing to do with using the bind operator within a monad. An example of a natural transformation would be transforming from one monad to another monad
- uxp8u61q 3y agoThe word "transformation" in that name has absolutely nothing to do with your use of the word "transform" ("transform the wrapped properties into some IO call"). MacLane could have decide to call natural transformations "widgets". My point is, besides the name (which is completely arbitrary), why would you even begin to believe this has something to do with "transforming properties into IO calls"? Nice shadow edit. For context, the previous comment used to consist of a single link to https://en.wikipedia.org/wiki/Natural_transformation https://en.wikipedia.org/wiki/Natural_transformation
- bowsamic 3y agoYeah to be honest it's kind of a red flag given the context to see a random term misappropriated in such a way
- deleted 3y ago[deleted]
- agentultra 3y agoYou can define abstractions very precisely in mathematics, that's what makes it useful. You have to get used to the fact that you're talking about the abstraction and not any specific instance/use of it. In the case of monads, the things that are useful which we can say about them: unit is a left identity for bind and also the right identity for bind, etc. What makes an abstraction useful, and is kind of essential in my opinion, are the laws. These do include every case because we don't say anything about specific terms or types, just the laws of bind (in the case of monads). I agree that people keep making them out to be some kind of mountain to climb when, after building up an intuition and learning the fundamental, it turns out they are more of a hill. However I think it takes a good mix of both the theory and application to appreciate how elegant and simple it is in the end.
- bowsamic 3y agoHere is Haskell's Monad: class Monad m where (>>=) :: m a -> ( a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a and these functions must obey the properties return a >>= k = k a m >>= return = m m >>= (\x -> k x >>= h) = (m >>= k) >>= h Anything other than the definition I gave is an analogy that will only work for certain examples, that is, unless you can mathematically prove that your analogy is isomorphic to this definition
- supermatt 3y agoYeah, my definition works for all those examples.
- bowsamic 3y agoOkay, then prove that your definition of a monad is isomorphic to the given definition
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- uxp8u61q 3y agoHow does your "definition" (I will take that to mean "an abstract wrapper for some properties that you can apply sequential transforms on" from your first comment) apply to e.g. the monad whose algebras are monoids?
- nextaccountic 3y ago> The transform is "transform the wrapped properties into some IO call", and all transforms are explicitly sequential. Not every monad has to do with IO. The oddity of Haskell is that Haskell has this IO type and every real world action has to produce an IO value, but the defining characteristic of IO isn't that it's a monad. Now, in the IO type, we use monads to sequence I/O operations, indeed (like "read something to the keyboard, then write this same something you read). But there are other monads that do other things! Monads always enable you to write sequential-looking code (through do notation), sure, but they don't need to execute sequentially - and most of them has nothing to do with IO! For example, the Cont monad enables writing code in continuation-passing style [0], and it's famously difficult to grok [1]. Suffice to say that it enables using the "call with current continuation" operator from Scheme (which doesn't work on IO, but works on Cont) [2] [0] https://www.haskellforall.com/2012/12/the-continuation-monad.html https://www.haskellforall.com/2012/12/the-continuation-monad... [1] https://stackoverflow.com/questions/3322540/how-and-why-does-the-haskell-cont-monad-work https://stackoverflow.com/questions/3322540/how-and-why-does... [2] https://stackoverflow.com/questions/20451022/how-to-interpret-callcc-in-haskell https://stackoverflow.com/questions/20451022/how-to-interpre...
- noelwelsh 3y agoYou should consider explanations within the context of which they are being given. The explanation above is sufficient for many cases, and it is a sufficient foundation for building further understanding. It's not helpful to tell someone their definition is wrong because it doesn't cover all possibilities. You shouldn't ask a 6-year old to define numbers and tell them they're wrong when they describe the integers. This would just bring confusion and anger to the child and makes you look like an arse. You might instead tell them it's a good explanation, but there are some numbers, like one half, that it doesn't include. So maybe we can make the description a bit bigger and include the rationals as well. This makes the child feel good because they were right about something, and also learned something and you feel good because you helped them learn. The same is true of adults.
- bowsamic 3y agoOkay but the point is that all these analogies claim to apply to all possibilities, and in fact this specific person has claimed that his analogy is a general definition of monads and so applies to all monads. > This makes the child feel good because they were right about something and also learned something and you feel good because you helped them learn. I'm not going to treat them like a child just to give them the impression that they contributed. They said something that I think is inadequate, so I told them that.
- deleted 3y ago[deleted]
- nerdponx 3y agoAt the same time, the general definition didn't pop up out of nowhere. I can't speak specifically for the history of monads, but very often these ideas start as specific ideas with very practical intuition, and are then carefully generalized. If you tried to learn linear algebra by starting with the general definition of linear transformations on vectors in an abstract space, you'd get nowhere. You need a reference point in order to effectively generalize. For example, I first came to understand functors/applicatives/monads as contexts, so the idea of a list being a monad was actually kind of weird to me. The other problem with monads (in Haskell) is that it's sometimes far from obvious what a particular monad actually does. If I see code like this: thing1 >>= frobify It tells me basically nothing about what the computer will actually do, unless I have some familiarity with the types involved. You see similar issues with things like context managers in Python, and with languages that support operator overloading for user-defined types. The difference is that we all have some generally correct intuition about what "+" means, so when we see that operator is overloaded on a custom type, we can at least have an idea about what it might do. But a programmer who lacks concrete intuition about what monads do will not be able to perform the same reasoning when they see ">>=" or "join".
- UncleMeat 3y agoOften times people don't want the general thing. They want to know how to solve a problem. An analogy I might give is memory ordering constraints in C++. If somebody comes to you and says "hey I've got some concurrent code that has these requirements", it might be thoroughly reasonable to give them a recipe that uses a particular sequencing constraint and operation pattern even though you could have a much more general discussion of the nature of happens-before relationships and proofs of correctness of concurrent algorithms. But somebody's eyes might glaze over. This is even true in mathematics. Sometimes you want to learn the full abstraction. Sometimes you want recipes that let you solve a PDE.
- tkz1312 3y agoI mean monads alone are not enough to do IO. Like it’s not possible to implement the IO monad in pure haskell. It’s more like the haskell runtime exposes a monadic API for its IO system. The general intuition that makes sense for me after a few years of full time haskell is that Monads are the thing that allows us to encode effectful computations within a pure language.