A SECOND MONAD: LOGGING

Haskell uses monads for a lot of things, but the basic reason is one important thing: in Haskell, functions are always free from side effects. As a result, all functions that logically do anything apart from the things allowed by functional programming (basically calculate a result based on their arguments and return it) must encode the results of whatever they did in their return values. The notion of monads revolves around the idea of having wrappers of data, chained together in a type-safe manner. Those wrappers usually store information in addition to the data itself — like the IsEmpty flag in the case of the Maybe monad.

One situation where programmers find themselves wanting to create side effects is the debug scenario in which information needs to be written out by a function that is otherwise functionally pure. How do you allow such a function to return not just its actual return value, but also some debug output? Why, with a monad of course!

Here is an implementation for the class Logger<T>, which is a monad:

image

public class Logger<T> {

  private readonly FCSColl::List<string> outputLines;

 

  private readonly T val;

  public T Value { get { return val; } }

 

  public Logger(T val, FCSColl::List<string> outputLines) {

    this.val = val;

    this.outputLines = outputLines;

  }

 

  public Logger(T val, string message) :

    this(val, new FCSColl::List<string>(message)) ...

Get Functional Programming in C#: Classic Programming Techniques for Modern Projects now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.