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. After 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)). Coming back to **F#** today just to miss some Scala constructs I really use a lot, the _Monad Writer_. Logging 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_. The 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. This should be as simple as: let writer = bind 5 "starting" The `bind` operation should return a _Writer_ which initial value is `5` and the initial value to be logged is `starting`. In order to do this, we need to define how a _Writer_ looks like. type Writer<'a, 'L> = AWriter of 'a \* List<'L> A 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. At this point, we only need the `bind` function so it creates the desired _Writer_. let bind = function | (v, itemLog) -> AWriter(v, \[itemLog\]) `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_. Now, 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` let map fx = function | AWriter(a, log) -> AWriter(fx a, log) In 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_. With only these two, we can start defining other functions that return _Writers_ (doing logging) while keeping referential transparency. Let’s define some functions we could use in our program. let sum x y = bind (x + y, "sum") let mul x y = bind (x \* y, "mul") let mod1 x y = bind (x % y, "mod") let minus x y = bind (x - y, "minus") Notice 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. As 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. By the using of `map` we can do transformations as follow. let str a = a.ToString() let to\_string a = a |> map str sum 5 5 |> to\_string Let’s take a closer look at this part. First, 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. What about getting things out of the _Writer_? Let’s define a simple way to extract the current value and the log we have been constructing so far. let run = function | AWriter(a, log) -> (a, log) `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_. let (v, log) = run (sum 5 5) or in more idiomatic **F#** let (v, log) = sum 5 5 |> run In here, `v` is the value `10` and `log` is `["sum"]`. Previously, 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. The missing operation is `flatMap`. let flatMap fx = function | AWriter(a, log) -> let (v, new\_log) = fx a |> run AWriter(v, List.append log new\_log) `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. Let’s look at an example which could be a little more enlightening. let result = sum 5 5 |> flatMap (mul 2) |> flatMap (mod1 25) |> flatMap (minus 10) The final value, `result`, is a _Writer_ where we can call `run`. let (v, log) = run result System.Console.WriteLine v for i in log do System.Console.WriteLine i This will print out: 5 sum mul mod minus Where `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. At 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. The entire code of _Writer_ looks like this module MonadWriter = type Writer<'a, 'L> = AWriter of 'a \* List<'L> let bind = function | (v, itemLog) -> AWriter(v, \[itemLog\]) let run = function | AWriter(a, log) -> (a, log) let map fx = function | AWriter(a, log) -> AWriter(fx a, log) let flatMap fx = function | AWriter(a, log) -> let (v, new\_log) = run (fx a) AWriter(v, List.append log new\_log) #### Conclusions The _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. Most 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. It 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). > Log safe, be functional.