And what if you have more functions that log things? There's a pattern here: for each function that returns a log along with a value, we want to combine those logs. This is a side-effect, and monads are great at side effects!

The Writer monad

The Writer monad is cool. "Hey dude, I'll handle the logging," says Writer. "Go back to your clean code and crank up some Zeppelin!"

Every writer has a log and a return value:

dataWriterwa=Writer{runWriter::(a,w)}

Writer lets us write code like this:

half8>>=half

Or you can use the <=< function, which does function composition with monads, to get:

half<=<half$8

which is pretty darn close to half . half $ 8. Cool!

You use tell to write something to the log. And return puts a value in a Writer. Here's our new half function:

Reader was always the renegade. The wild card. Reader is different because it's
only field is a function, and this is confusing to look at. But we both
understand that you can use runReader to get that function:

And then you give this function some state, and it's used in greeter:

runReadergreeter$"adit"=>"hello, adit!"

So when you use >>=, you should get a Reader back. When you pass in a state to that reader, it should be passed through to every function in that monad.