This time, instead of printing, we build up a string as a side effect. printplus() is implemented exactly as before, without knowledge of how to handle side effects, and yet it correctly handles strings returned as a side effect and concatenates them together. The magic is bind() which allows a function expecting an int input to be applied to a WriterInt.

I'm hoping that programmers of languages such as C can now begin to see the pattern shared by these examples.

Anyway, this is all just stalling for time while I try to get my quantum computation code working.

My goal here isn't to do anything useful but to simply translate one of the simplest monads into C++ to make the way it works more apparent to people with a C++ background. It's not something that anyone would really write in C++, it's just a baby example in the hope that it illustrates the pattern. A more sophisticated monad like the list monad allows you to do things like logic programming in Haskell, something that is much more difficult to implement in C++ and really leverages the usefulness of monads. But it helps to understand these simple examples first.

In pure functional programming languages you aren't allowed to cause side effects. The only way a function can 'interact' with the outside world is to return something. So if you have a function that needs to return a number, but has a certain side effect, the only way to do this is to return the number and return some data 'containing' the side effect. But that's a pain in the ass - you have to write all of your code to return multiple values, and you have to write plumbing code to pass these side-effect containing values around. What monads can do is give a uniform API to side-effect containing data so you can just concentrate on the number that you want to return, and have the side-effect carried along automatically in the background. What's neat about monads is the same API can be used for many different problems, not just handling side-effects.

So half the time when dealing with monads we're solving a problem that we've caused in the first place by using a pure functional language. (But sometimes it's worth using a pure functional language because of other benefits.) The other half of the time we're using monads because they provide facilities that are very hard to implement otherwise - such as logic programming or continuation passing style. I've not given C++ examples of the latter because it would be way too hard. So I've only given examples of things that you can easily implement already in C++.

If you ever get a chance, check out the list monad in Haskell. It's beautifully simple, and yet it takes a considerable amount of work to implement the same thing in C++.