Monads Explained Quickly
21–30 of 42 posts
Re: Monads Explained Quickly
#22There are so many attempts at describing what monads are, but so few attempts at teaching why you would want to use a monad, and where it would be beneficial over other coding styles.
At risk of adding to the pile of half baked pedagogy, here's my take at why they're useful. The operation to chain things together (denoted >>= and pronounced bind) in the Maybe monad has type Maybe a -> (a -> Maybe b) -> Maybe b In a more a java-like notation, this is like Maybe bind(Maybe , Function >) The Haskell notation says that it's a function that takes two arguments (separated by ->). The first argument (May…
And then you need to write or convert all your functions to return maybe values rather than just plain values.
All of this could be easily done with exceptions. Why do all that when something simple like an exception will do, is easily understood, and easily coded?
If there are other common usage patterns where monads are great fit, I'd love to hear it. But, given the examples of usage I've heard about, they seem to be a somewhat painful mechanism which are useful only in a few obscure cases.
Admittedly, I do not understand category theory, so I can accept that I might not be able to see the benefit unless I do.
Re: Monads Explained Quickly
#23What language is this? It looks like Javascript, but with some additional operators, such as "=>".
Re: Monads Explained Quickly
#24Re: Monads Explained Quickly
#25Re: Monads Explained Quickly
#26Earlier quoted context omitted.
Everyone here is saying the article is wrong, but no one really adds anything or corrects the author. Can you expand?
The problem with monads is that truly understanding monads renders one completely incapable of explaining monads to anyone uninitiated. This seems to be the most fundamental property of the monad. It seems, from the plethora of monad explanation articles that get posted here, that many people, in their hubris, think they've learned monads and think that they will succeed where so many others have failed and come up w…
Re: Monads Explained Quickly
#27Earlier quoted context omitted.
At risk of adding to the pile of half baked pedagogy, here's my take at why they're useful. The operation to chain things together (denoted >>= and pronounced bind) in the Maybe monad has type Maybe a -> (a -> Maybe b) -> Maybe b In a more a java-like notation, this is like Maybe bind(Maybe , Function >) The Haskell notation says that it's a function that takes two arguments (separated by ->). The first argument (May…
For the "maybe a" case, you then need to take all of your code and place it in some machinery that knows what "maybe" means, and how to extract "a" from it. And then you need to write or convert all your functions to return maybe values rather than just plain values. All of this could be easily done with exceptions. Why do all that when something simple like an exception will do, is easily understood, and easily code…
It's all about being explicit. In many languages, even statically typed ones, like C++ and Haskell, exceptions aren't reflected in the type system. This makes it easy to forget to handle an exception.
If you are not convinced about the utility of Maybe monads, maybe you can find other monads that aren't as easily mapped to other concepts in imperative languages, like the various parser monads, or just the List monad (which can be used to implement a simple parser).
You don't need to understand category theory. Learning category theory is only just something nice-to-have; it can help you devise new and novel abstractions, but hey, perhaps 99% of the code don't really need new abstractions.
Re: Monads Explained Quickly
#28Contemplate until enlightened. But don't write YAMT afterwards.
Re: Monads Explained Quickly
#29Earlier quoted context omitted.
At risk of adding to the pile of half baked pedagogy, here's my take at why they're useful. The operation to chain things together (denoted >>= and pronounced bind) in the Maybe monad has type Maybe a -> (a -> Maybe b) -> Maybe b In a more a java-like notation, this is like Maybe bind(Maybe , Function >) The Haskell notation says that it's a function that takes two arguments (separated by ->). The first argument (May…
For the "maybe a" case, you then need to take all of your code and place it in some machinery that knows what "maybe" means, and how to extract "a" from it. And then you need to write or convert all your functions to return maybe values rather than just plain values. All of this could be easily done with exceptions. Why do all that when something simple like an exception will do, is easily understood, and easily code…
return readFromFile("file.txt").map(text -> parse(text));
In this case, I'm only going to parse the contents of the file if they exist. Normally, I'd have to write: try {
return readFromFile("file.txt");
} catch (SomeFileException e) {
// Handle it
}
Of course, the top one lets you handle it up-stream, but the specific thing about using types instead of exceptions is that you're forced to handle it at some point, but that doesn't mean you have to write substantially more error-checking code.Now with a monad, I can do the same kind of abstraction even more powerfully. Say I have a function that may return an exception and I want to run that over the file:
return readFromFile("file.txt").bind(text -> writeToFile("some_other_file.txt", text);
In this case, writeToFile could fail. If it does, it's going to return Nothing. Otherwise, it returns Just (the text we wrote). Now, if we were to just use .map() here, we would end up with Maybe>. We don't want that, that's redundant information. It either failed, or it didn't. In order to help us out, the .bind() function consolidates the two Maybes into one Maybe, so we get back a Maybe. Here is where monads really pay off: with exceptions, we'd have to handle them at multiple levels, but using .bind() we're able to only handle them once (by checking in our main function, for example, what we got back from the entire process).If we read the definition of bind here, it's a lot more clear (here I'm specializing the return types for more clarity, but in Haskell it'd be a more generic definition):
Maybe bind(Function> f, Maybe x) {
switch (x) {
case Just(theString):
// Notice, we're not returning Just(f(theString)).
// We let f() determine whether we return back something
return f(theString);
case Nothing:
return Nothing;
}
}