We want to write functions that don't involve IO (which we call "pure functions"), but we want to be able to use these functions on values that have been tainted by IO.
Ex.
The function abs takes an Int and returns its absolute value. No IO there; it takes an Int and returns an Int. However, in a pure language like Haskell, an integer that has been obtained through IO is of type "IO Int". Because Haskell is a pure language, we see that value as "tainted" by IO; it any anything derived from it are irreversibly tainted. A monad lets us pull the Int out of the IO context, get its absolute value with abs, and then stick that back into the IO context. That way, IO-tainted stuff keeps its label warning us that it's IO-tainted, but we can still use pure functions on it. This is necessary because if abs returned an IO Int, we wouldn't know whether or not abs does IO. That's to say, we couldn't get pure values back when we process pure values with abs.
This can be done for any "context", but IO was the most pressing one, and monads are what made IO in pure languages easy enough for them to be usable for everyday problems.
Also, the Paul Graham worship here is pretty bad, but being suspicious of something just because he hasn't mentioned it in an article is really bad.
We want to write functions that don't involve IO (which we call "pure functions"), but we want to be able to use these functions on values that have been tainted by IO.
Ex.
The function abs takes an Int and returns its absolute value. No IO there; it takes an Int and returns an Int. However, in a pure language like Haskell, an integer that has been obtained through IO is of type "IO Int". Because Haskell is a pure language, we see that value as "tainted" by IO; it any anything derived from it are irreversibly tainted. A monad lets us pull the Int out of the IO context, get its absolute value with abs, and then stick that back into the IO context. That way, IO-tainted stuff keeps its label warning us that it's IO-tainted, but we can still use pure functions on it. This is necessary because if abs returned an IO Int, we wouldn't know whether or not abs does IO. That's to say, we couldn't get pure values back when we process pure values with abs.
This can be done for any "context", but IO was the most pressing one, and monads are what made IO in pure languages easy enough for them to be usable for everyday problems.
Also, the Paul Graham worship here is pretty bad, but being suspicious of something just because he hasn't mentioned it in an article is really bad.