The Writer monad is a programming design pattern which makes it possible to compose functions which return their result values paired with a log string. The final result of a composed function yields both a value, and a concatenation of the logs from each component function application.

Demonstrate in your programming language the following:

 Construct a Writer monad by writing the 'bind' function and the 'unit' (sometimes known as 'return') function for that monad (or just use what the language already provides)
 Write three simple functions: root, addOne, and half
 Derive Writer monad versions of each of these functions
 Apply a composition of the Writer versions of root, addOne, and half to the integer 5, deriving both a value for the Golden Ratio φ, and a concatenated log of the function applications (starting with the initial value, and followed by the application of root, etc.)
#include <cmath>
#include <iostream>
#include <string>
 
using namespace std;
 
// Use a struct as the monad
struct LoggingMonad
{
    double Value;
    string Log;
};
 
// Use the >> operator as the bind function
auto operator>>(const LoggingMonad& monad, auto f)
{
    auto result = f(monad.Value);
    return LoggingMonad{result.Value, monad.Log + "\n" + result.Log};
}
 
// Define the three simple functions
auto Root = [](double x){ return sqrt(x); };
auto AddOne = [](double x){ return x + 1; };
auto Half = [](double x){ return x / 2.0; };
 
// Define a function to create writer monads from the simple functions
auto MakeWriter = [](auto f, string message)
{
    return [=](double x){return LoggingMonad(f(x), message);};
};
 
// Derive writer versions of the simple functions
auto writerRoot = MakeWriter(Root, "Taking square root");
auto writerAddOne = MakeWriter(AddOne, "Adding 1");
auto writerHalf = MakeWriter(Half, "Dividing by 2");
 
 
int main()
{
    // Compose the writers to compute the golden ratio
    auto result = LoggingMonad{5, "Starting with 5"} >> writerRoot >> writerAddOne >> writerHalf;
    cout << result.Log << "\nResult: " << result.Value;
}
 