dons' explanation will be better/more rigorous than mine, but in a more familiar syntax (Python), let's say you've got some functions:
def get_user(id):
# returns None if no such user exists
return Database.Users.get(id)
def send_message(user):
user.send(message)
def main():
user = get_user(1)
# uhoh -- this could be None and we didn't handle it!
send_message(user)
So, we add a None check:
def main():
user = get_user(1)
if user != None:
send_message(user)
But... what if we want to log the status of that send_message call?
(Note that this is a contrived example, please don't critique the general dumbness ;)).
Now...
def main()
user = get_user(1)
if user != None:
response = send_message(user)
if response != None:
log(response)
As you can see, it's getting a bit hairy. But, what if we had a class that dealt with the Nones for us? This is what a monad is: an interface, that many different instances implement, which provides some behavior. The following only deals with single-argument functions, but:
And, boom, the Nones are handled. Real, non-contrived Monads do more (and implement other behaviours -- like in dons' example, the Either response, or the Maybe monad, etc.), but hopefully this demonstrates the strength. Haskell's typically used as the example language, because there's syntax sugar in Haskell for making dealing with Monads prettier :).
Having finally grokked them, it surprised me how simple the concept is. I think for people (like me!) coming from Java, Python, etc. who've not had to deal with the concept, there's this sort of imbued myth that they're a much more difficult concept than they really are. It's as simple as: a Monad is an interface, that can be implemented, that provides a construct for executing code in.
Please forgive any blinding mistakes I've made in my code.
Well, the meaning of >>= is impossible to grok in this context because the meaning of "bind" isn't clear. In fact, most of the Monad interface (bind, lift, etc.) is pretty unclear to most people because, I think, it doesn't map onto other languages' concepts.
In fact, I might say that the worst possible way to explain Monads to someone unfamiliar with the subject is to use Haskell's monadic syntax.
Ugh, this made more sense than anything else I've ever read about monads. This, together with the Wikipedia sentence that monads are "programmable semicolons", helped me finally understand what they actually are.
Like the other commenters said, I don't understand why someone would use Haskell syntax to explain monads. If you know Haskell, you already know what monads are!
I think it's always worth studying Free monads to understand them a bit more completely. After you can see how to construct and map free monads then there's not much left to the concept to debate.
Thank you for taking time to provide a meaningful example in a commonly used language as it makes it pretty clear why monads could be considered useful in certain scenarios. You have managed to explain monads more clearly to me with a single post than any other article I've ever read.
Now...
As you can see, it's getting a bit hairy. But, what if we had a class that dealt with the Nones for us? This is what a monad is: an interface, that many different instances implement, which provides some behavior. The following only deals with single-argument functions, but: Now, we... And, boom, the Nones are handled. Real, non-contrived Monads do more (and implement other behaviours -- like in dons' example, the Either response, or the Maybe monad, etc.), but hopefully this demonstrates the strength. Haskell's typically used as the example language, because there's syntax sugar in Haskell for making dealing with Monads prettier :).Having finally grokked them, it surprised me how simple the concept is. I think for people (like me!) coming from Java, Python, etc. who've not had to deal with the concept, there's this sort of imbued myth that they're a much more difficult concept than they really are. It's as simple as: a Monad is an interface, that can be implemented, that provides a construct for executing code in.
Please forgive any blinding mistakes I've made in my code.