Monads/Writer monad: Difference between revisions
Content added Content deleted
(A Python implementation) |
(Added C++ implementation) |
||
Line 187: | Line 187: | ||
divided by two -> 1.61803398875" |
divided by two -> 1.61803398875" |
||
}</pre> |
}</pre> |
||
=={{header|C++}}== |
|||
<lang cpp>#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 Writer = [](auto f, string message) |
|||
{ |
|||
return [=](double x){return LoggingMonad(f(x), message);}; |
|||
}; |
|||
// Derive writer versions of the simple functions |
|||
auto writerRoot = Writer(Root, "Taking square root"); |
|||
auto writerAddOne = Writer(AddOne, "Adding 1"); |
|||
auto writerHalf = Writer(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; |
|||
} |
|||
</lang> |
|||
{{out}} |
|||
<pre> |
|||
Starting with 5 |
|||
Taking square root |
|||
Adding 1 |
|||
Dividing by 2 |
|||
Result: 1.61803 |
|||
</pre> |
|||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |