I found myself writing some code like this a week or two ago:
string testPath = ...; func1(testPath, ...); func2(testPath, ...); ...
I thought it was annoying that I had to keep repeating the same argument to every function call and started thinking about ways that I could automatically “thread” it. By just thinking that word I was taken to the world of Haskell and thought that the Reader monad would be great here. I even thought of implementing it in D, until I realised… that’s just an immutable object! I don’t need a monad, just a struct or a class:
struct Foo { string testPath; func1(...) const; func2(...) const; }
In most OOP languages I don’t need to pass anything when func1 or func2 are called, and they both implicitly have access to all the instance variables, which is exactly what I wanted to do anyway. In D I can even get something resembling Haskell do notation by writing the client code like this:
with(immutable Foo()) { func1(...); func2(...); }
(as opposed to):
auto foo = immutable Foo(); foo.func1(...); foo.func2(...);
I can’t believe it took me this long to realise it, but the Reader, Writer and State monads are just… objects. Reader is immutable, but I just showed how to get the same effect in D. It’d be similar in C++ with a const object, and the lack of the with keyword would make it more verbose, but in the end it’s very similar.