
Monads you can understand (2015) - jxub
https://web.archive.org/web/20160711101758/https://hyegar.com/2015/10/12/monads-you-can-understand/
======
theaeolist
The conclusion of the post is, literally, that you don't need to understand
monads. Not what the title sells.

------
mikekchar
I've been trying to find idiomatic ways of explaining monads to people who
already know how to program, but may not be using functional languages.
Possibly this explanation will be useful. I would be happy for some criticism.

A monad is a type of functor. In terms of programming a functor is a
collection: a data structure that can hold a piece of information. Functors
have a function related to them, usually called "map" or "fmap" (for 'functor
map'). "map" takes the information out of the collection, transforms it with a
function that you pass to "map" and then puts it back in to the same kind of
collection. Most programmers have experience with this if they use a modern
programming language (though they may not have known it was a "functor" that
they were using).

Quick note: I always found the word "functor" to be confusing because it
sounds like it should _do_ something rather than _be_ something. This is true
in category theory where the concept originates, but the computer programming
implementation turns out differently. I'm going to try to avoid category
theory in this explanation, but it's still interesting to look into.

Like I said, a monad is just a special type of functor. With a functor, it is
possible to change the type of the information you are working on with the
function you pass to "map". You might have a function that converts an
character to an integer (maybe just giving its ASCII representation). Then you
can pass that function to map and your collection of characters will be
converted to a collection of integers. Monads (used as monads) don't allow
this.

Monads use a function called "bind". It works a bit like "map" except that the
function you pass to "bind" needs to return the resultant monad rather than
just the transformed information. For example, if you have a container that
contains an integer, you need to pass a function to "bind" that returns a
container that contains an integer. You can transform the integer in the
function, but you must always return a container with the integer inside.

Why do you want a monad? It is so you can chain actions knowing that bind will
always return the exact same type. A place where I often build monads is in
refining a search. I start with a collection of data. I call "bind" with the
refinement function. This will return a collection of data. I call "bind" with
the next refinement function. I just keep doing that until I've finished the
refinement and I'm left with the refined collection of data. I can always add
more refinements to the chain because I know that "bind" will always return a
container of search results.

Implementation detail: You might be wondering why "bind" has to return a
monad, while "map" just returns the transformed data (after which "map" puts
it back into the functor). "map"'s behaviour seems much more convenient. The
reason is so you can handle data structures that have optional data. Imagine
our monad can contain either search results _or_ an error. If the monad
returns search results, "bind" will call the function passed to it. Otherwise
it will just return the monad containing the error. This allows you to return
a monad containing an error from your function. If you were using "map", there
is no way to return that error.

And that's basically it. Collections are almost always functors meaning that
you can define map on them. You use map to apply general transformations on
the data in the collection. Most functors can also be monads which means you
can implement bind on them. You use bind to successively apply operations on a
data structure, always getting the exact same type of data structure back.
bind forces the function passed it it to return a monad, which allows you to
store optional information in the monad.

Final aside: I think that monads are as important in OO as they are in FP,
IMHO. In fact, an object itself is a monad: Write a method on an object that
does a transformation of the data in the object and returns a new object of
the same type with the transformed data. In this case, the application of the
method (usually "." in most programming languages) is "bind" and the method is
the function that you passed to bind. However, I'll warn you that if you are
implementing monads this way, avoid subclass polymorphism unless you want to
go crazy ;-)

Edit: spelling

~~~
arijun
You made it very clear, thank you. However, do you have more examples of what
they’re used for? Given your example, I still don’t understand why monads are
so important.

~~~
knitHacker
I think this is the why monads are hard to understand. It's hard to come up
with a general example of why they are useful and anything beyond they
significantly simplify a lot of common cases you run into with functional
programming quickly get convoluted.

I didn't really understand monads until I ran into really long / repetitive /
ugly code when writing Haskell and then reading a book and realizing they
could be used to simplify the parts of my code that frustrated me.

I think the biggest reason they are useful is because data and the container
around it can be treated independently and gives a good common interface for
container behavior.

------
RcouF1uZ4gsC
Do you really want to understand monads? Here is how to do that in 2 steps.

1) Go to [https://www.haskell.org/](https://www.haskell.org/) and install
haskell for your platform

2) Go to [http://learnyouahaskell.com/](http://learnyouahaskell.com/) and work
through the book.

I guarantee that by the time you finish going through it, you will have a good
understanding of Monads.

Trying to understand monads when you have only worked with imperative
languages is like trying to understand heterosexual sex without ever having
seen a member of the opposite sex.

~~~
geezerjay
The correct answer to the question "what's a monad?" is not "learn haskell".
That answer misses the point and is not helpful at all.

