| I'll try and keep it simple. It helps make code more readable. When I see a bunch of Maybe monads, for example, I can instantly know that the programmer's intent was maybe to not just have a type safe null and avoid null pointer exceptions, but also to possibly make use of Maybe's toxicity. What I mean by toxicity is you know how in some languages you have "not a number" aka NaN? A NaN times / divided by / added to / subtracted from anything is a NaN, that means that if you have a complex formula, if you throw a NaN in there anyway you get back a NaN. Maybe works the exact same way but with all functions not just arithmetic operators. That's what I mean by its toxicity. Without Maybe you'd have to explicitly apply that logic everywhere you'd otherwise apply a monadic "join." The reader would then have to study your code much more carefully to understand that intent, and probably look at it with some skepticism that the toxicity works perfectly every time or is in every place you might expect. And of course not everyone values brevity and expressiveness, but when done right it makes code more readable not less, and Monads done right facilitate that. Maybe's toxicity is just an example of pretty much any "magic" you can build into a Monad. You could for example have a Future Monad that will handle asynchronous control flow for you. As a side matter, it's not just working around Haskell's strict type system that make Monads a good fit for IO, but also Haskell's non-strict execution.. monads help things happen in the right order which is crucial for IO. That's kind of neat when you think about - the bridge between the mathematical rigor of pure functional code and real world devices that make computing useful. Functional purity makes code easier to reason about and less error-prone. |