A few years ago, I started learning **F#**. That took me to the path of building a full compiler for a pure functional language in **F#** using only a purely functional approach.\n\nAfter that, I have moved to Scala and never came back to the .NET Framework. However, sometimes I miss the simplicity and expressivity of **F#**. I have demonstrated so in some of the posts I have written before such as ([**_|> Operator in Scala_**](https://hackernoon.com/operator-in-scala-cbca7b939fc0)**_,_** [**_Higher order functions, what are they?_**](https://hackernoon.com/higher-order-functions-what-are-they-be74111659e8) **_and_** [**_What Comes Next to Higher Order Functions_**](https://medium.com/@anicolaspp/what-comes-next-to-higher-order-functions-2279d07b4efc)).\n\nComing back to **F#** today just to miss some Scala constructs I really use a lot, the _Monad Writer_.\n\nLogging is an important part of our applications. However, we rarely do pure functional logging. I am not going to go over why or why not to do functional logging, but we are going to see how simple is to write and use pure functional logging in **F#** by using a _Monad Writer_.\n\nThe first thing we need to do, it’s a way to create a _Writer_. Specifically, we want to be able to get access to the initial writer that we are going to use for our next operations.\n\nThis should be as simple as:\n\nlet writer = bind 5 "starting"\n\nThe `bind` operation should return a _Writer_ which initial value is `5` and the initial value to be logged is `starting`.\n\nIn order to do this, we need to define how a _Writer_ looks like.\n\ntype Writer<'a, 'L> = AWriter of 'a \\* List<'L>\n\nA simple discriminated union is more than enough. We need a generic type `‘a` and the generic `‘L` which is our log. Of course, we are not constrained to log only `string`. The elements of the log can be, in fact, of any type. For convenience and simplicity, we are going to use `string` most of the time, but we could use any other type as part of the log.\n\nAt this point, we only need the `bind` function so it creates the desired _Writer_.\n\nlet bind = function \n | (v, itemLog) -> AWriter(v, \\[itemLog\\])\n\n`bind` is a function that receives two args, a generic value `v` and the first item to be logged, `itemLog` and then it returns our initial _Writer_.\n\nNow, we need a way to map over the value of the _Writer_, so we can change types of the boxed value without affecting the log. Let’s see how we can write `map`\n\nlet map fx = function \n | AWriter(a, log) -> AWriter(fx a, log)\n\nIn here, `map` takes another function `fx` that is applied over the _Writer_ value `a` by creating a new _Writer_. Notice we never mutate a Writer, we just create new _Writers_.\n\nWith only these two, we can start defining other functions that return _Writers_ (doing logging) while keeping referential transparency.\n\nLet’s define some functions we could use in our program.\n\nlet sum x y = bind (x + y, "sum") \nlet mul x y = bind (x \\* y, "mul") \nlet mod1 x y = bind (x % y, "mod") \nlet minus x y = bind (x - y, "minus")\n\nNotice all these functions only have one single responsibility, to sum, to multiply, to find the module, and calculate difference. They have no knowledge of global loggers and they don’t append anything to a shared state. They are very small, very simple to test; they are pure functions.\n\nAs we can see, all of them return a _Writer_ through the function `bind`. Thanks to the advance **F#** type system and type inference, defining functions like this is a very easy task.\n\nBy the using of `map` we can do transformations as follow.\n\nlet str a = a.ToString()\n\nlet to\\_string a = a |> map str\n\nsum 5 5 |> to\\_string\n\nLet’s take a closer look at this part.\n\nFirst, we created a _Writer_ with value `5 + 5 = 10` and log `["sum"]` and then we call `to_string` which basically calls `map` so the result is a _Writer_ with value `"10"` and the same log `["sum"]`. We have modified the value of the _Writer_ via `map` without touching the log.\n\nWhat about getting things out of the _Writer_?\n\nLet’s define a simple way to extract the current value and the log we have been constructing so far.\n\nlet run = function \n | AWriter(a, log) -> (a, log)\n\n`run` is a function that receives a _Writer_ and returns in a tuple form the value and the log. Now we could take a look at the content of the _Writer_.\n\nlet (v, log) = run (sum 5 5)\n\nor in more idiomatic **F#**\n\nlet (v, log) = sum 5 5 |> run\n\nIn here, `v` is the value `10` and `log` is `["sum"]`.\n\nPreviously, we have defined different functions where all of them return _Writers_ (_sum, mul, mod1, minus_), yet we don’t have a way to combine the defined operations so the result of each of them gets aggregated into a single log.\n\nThe missing operation is `flatMap`.\n\nlet flatMap fx = function \n | AWriter(a, log) -> \n let (v, new\\_log) = fx a |> run \n AWriter(v, List.append log new\\_log)\n\n`flatMap` receives a function of type ``'a -> Writer(b, List<`L>`` and returns a new _Writer_. If we take a closer look, `flatMap` is the one in charge of aggregating the logs from multiple Writers.\n\nLet’s look at an example which could be a little more enlightening.\n\nlet result = \n sum 5 5 \n |> flatMap (mul 2) \n |> flatMap (mod1 25) \n |> flatMap (minus 10)\n\nThe final value, `result`, is a _Writer_ where we can call `run`.\n\nlet (v, log) = run result\n\nSystem.Console.WriteLine v\n\nfor i in log do \n System.Console.WriteLine i\n\nThis will print out:\n\n5 \nsum \nmul \nmod \nminus\n\nWhere `5` is the result of `5 + 5 = 10 * 2 = 20; 25 % 20 = 5; 10 — 5 = 5` and the the log in the order operations were executed.\n\nAt this point, we have fully defined a _Monad Writer_ in **F#** in it’s simplest way. We could actually add more functionality to it, but let’s keep it as simple as possible for this exercise.\n\nThe entire code of _Writer_ looks like this\n\nmodule MonadWriter = \n \n type Writer<'a, 'L> = AWriter of 'a \\* List<'L> \n \n let bind = function \n | (v, itemLog) -> AWriter(v, \\[itemLog\\]) \n \n let run = function \n | AWriter(a, log) -> (a, log) \n \n let map fx = function \n | AWriter(a, log) -> AWriter(fx a, log) \n \n let flatMap fx = function \n | AWriter(a, log) -> \n let (v, new\\_log) = run (fx a) \n AWriter(v, List.append log new\\_log)\n\n#### Conclusions\n\nThe _Monad Writer_ is a very elegant way to keep your functions pure while they have a single responsibility, such doing small operations like `a + b`. Also, by following this p_attern,_ we avoid injecting loggers all around our code, or worse, accessing to global loggers which can be very dangerous when used in multithreading / parallel execution contexts.\n\nMost of us when working on OO languages have used the _bad_ loggers, but that only makes deeper dependencies in code while breaking the Single Responsibility Principle.\n\nIt is or solely decision to move to a functional way of doing logging, especially in distributed systems. You can take a look how to do in Apache Spark by reading [**_How to log in Apache Spark, a functional approach_**](https://hackernoon.com/how-to-log-in-apache-spark-a-functional-approach-e48ffbbd935b).\n\n> Log safe, be functional.