9 ms·
Wait. Assuming one does not need or want to learn Haskell, what would then be a purpose of learning about monads? There seems to be a disproportionate amount o
by yoz-y 5y ago
Wait. Assuming one does not need or want to learn Haskell, what would then be a purpose of learning about monads?
There seems to be a disproportionate amount of tutorials about monads. Not being able to provide sufficient amount of examples in other languages makes monads seem quite less useful. Maybe next article to write is “why should you learn about monads”.
- herbstein 5y agoThe point about Haskell is that it forces you to, or at least heavily nudges you to, understand monads and the rest of the typeclass hierarchy. However, you use the properties of monads all the time. The Stream APIs in JAVA and LINQ in C# are examples of abstractions built around Monads and their properties. The definition of a monad, as it relates to programming, emerges when you realize that an Option type, a Result/Either type, a List type, and a bunch of other non-container types all have the equivalent of a `flat_map` function. Write out a few mathematical rules for how a well-behaved implementation should compose and you have a Monad and its rules. This is why another approach to learning monads that isn't focused on the theory introduces it as a design pattern instead. I find this to be great for intuition but horrible for understanding personally, having used both approaches to teach people about Monads IRL.
- lmm 5y agoMonads are a very effective technique for expressing custom requirements in your type system, e.g. "this function must be called only in a database transaction", "this function writes an audit log entry", "this function requires this level of authorization". The kind of thing you might think you would have to do via AOP/decorators/monkeypatching, you can usually do in plain old code (with all the attendant advantages) via a monad. If your type system can't express them then you lose most of the advantages and they're pretty pointless.
- calo_star 5y agoI find this perspective intriguing, can you elaborate on that? For example why `m a -> (a -> m b) -> m b` but not something else?
- lmm 5y agoSome people describe monads as "programmable semicolons" - they're pretty much the general concept of sequencing, "do this then do that", or indeed of imperative code. I don't think they're necessarily the ideal abstraction - something like ArrowChoice is "better" in a lot of cases - but in practice they seem to come up a hell of a lot, you can represent almost anything as a monad.
- wyager 5y agoWhy monads and not something else? Because monads appear to be a/the mathematical structure underlying the denotation of programs with effects. Why that type signature? You only have two options: that, or m (m a) -> m a. The former is more popular for ergonomic reasons mostly. It doesn’t really matter.
- uryga 5y ago> why `m a -> (a -> m b) -> m b` but not something else? it's basically continuation-passing-style (`a -> m b` is the "continuation"), you might as well ask "why can you represent so many control-flow things using CPS?". idk why, but you can! from another angle, you could compare Monad with the less powerful Applicative. a formulation[0] that's easier to parse than the usual one[1] is: class Functor f => Applicative f where unit :: f () pair :: f a -> f b -> f (a, b) if you're familiar with JS Promises, a rough analogy would be >>= (Monad) Promise.then pair (Applicative) ≈ Promise.all unit (Applicative) = return (Monad) = Promise.resolve ignoring parallelism, you can implement Promise.all using Promise.then, but not the other way around. --- [0] Called "Monoidal" here: https://stackoverflow.com/q/45267953 https://stackoverflow.com/q/45267953 [1] https://en.m.wikibooks.org/wiki/Haskell/Applicative_functors#The_Applicative_class https://en.m.wikibooks.org/wiki/Haskell/Applicative_functors...
- rocqua 5y agoBecause so many types above are m of something. You as a programmer get to decide how that m type works, so you have a lot of control there.
- sfvisser 5y agoMonads (and functors and applicative) are definitely useful outside of Haskell. At first glance monads seem less useful in languages with builtin mutable state, and freely allowing side effects. However, if you’re writing somewhat more high-level domain specific code there are plenty of concepts that can be modeled using functors and monads very elegantly. Parser combinators, distributed data fetching, reactive data streams, composable tree traversals, etc I use them all the time in for TypeScript.
- _ph_ 5y agoIf monads exist outside of Haskell, why isn't there a text which explains them with out Haskell knowledge? Where would I find such a text and description? I would really like to understand what they are, but so far have not been able to find any explanation which tries to explain them in terms of english, math or some commonly known programming language.
- Huggernaut 5y agoThis is probably the best resource I've come across for discussing this subject: https://fsharpforfunandprofit.com/posts/elevated-world/ https://fsharpforfunandprofit.com/posts/elevated-world/
- _ph_ 5y agoThanks, but the article loses me at what this "elevated world" is. It doesn't even try to explain what it is and quickly goes over to F# syntax, which I don't understand. Why is there no explanation in the terms of English, math, and any common programming language? If Functors and Monads are real concepts, they should be describable in the terms listed above, if they are only describably in terms of functional languages, I would consider them a pure artifact of those languages :)
- pests 5y agoThere isn't one unique elevated world, as he goes on to say. Two he lists we are familiar with - options and lists. If you've ever used Option(Some|None) and pulled out a value from Some - the Option is the elevated world, the Some|None is the elevated value.
- mrspeaker 5y agoIf you never want to learn Haskell (or PureScript or similar) then the author even says in the `If They're So Wonderful Why Aren't They In My Favorite Language?` section: "If you don't need IO sequencing, or purity because your language doesn't care about purity, or the list implementation's nondeterminism because that's a parlor trick, or STM because your ecosystem doesn't use it... there's not much point to worrying about it. Monad implementations in languages other than Haskell fail to take off because there generally isn't even a single thing that is improved by working with it through a monad interface, let alone a family of such things." "[...]It's definitely an interesting idea, and if you are a curious programmer, it's worth learning about this particular interface and what it can do. But it's not something you generally directly take back to your language"
- morelisp 5y agoThere are two subtly different things here, "monads" as a concept and specific monads. If I ask you, what's the thing in common between async functions, nullable types, exception handling, sequenced evaluation, and arrays, and you only know, say, Java, Scheme, and Python - you'll probably not see anything. Nonetheless, these are all monads, and learning specific monads helps in lots of other languages. Optionals are nice in Java. Arrays in Lisps. Error handling in Scala. But the "universality" of monads escapes these languages. I would kill for better monadic error handling in Go, but conversely I would have little use for monadic I/O or futures. The critical mental step is seeing the commonality in all of these, which is really only possible in languages at that level of type sophistication. And necessary in Haskell where the particular combination of purity, laziness, and HKTs means monads are the only way decent way to do most of these. Once you see that commonality you can develop tools - patterns of mental reasoning about code and idioms for writing code - you can also use when dealing with the specific monads or nearly-monads in other languages. But you can't show that property in examples in a single other languages, and it's difficult to show how some deep structure is shared in examples spanning five languages.
- yoz-y 5y agoI think that in the end I would wish for an article that distills the last part. "How to benefit from monadic nature of various concepts in any language". I believe that it goes beyond flatMapping over async functions, nullable types and arrays, and using higher order functions.
- alephu5 5y agoThere are many examples of monadic patterns used in other languages, in particular to encapsulate failure or nullable values. I've also seen a lot of codebases that have implemented a custom "pipeline" class that can be composed together, such that some transformation or effect occurs every time a value passes from one pipeline to another. These are usually monads too, allowing for some minor deviations from the formal definition. Nevertheless language ecosystems outside Haskell, scala and F# don't recognise this as a general programming pattern, although given the current direction towards FP in the JavaScript and rust communities I think it's a matter of time.