In simple words, monad is a container, a box for a value. It contains and provides additional functionalities.
For example if we have value type, like int, we cannot set its value to null, that represents nothing. A value type has to have some value. But what if we want to sometimes have value and sometimes not?. Nullable<int> is the answer, or as it is seen more often int?. So Nullable<T> may or may not contain value, we can check if it has, by using HasValue() method, and then use it, by using Value property. Nullable<T> is an implementation of the Maybe monad.
What’s cool about that you may ask. Well…
- readability – from the first sight you can tell that one property may but doesn’t have to contain value
- avoiding nulls means avoiding NullReferenceExceptions – before accessing value you should always check if the value exists
There are many monads in this world… Result represents result of operation that might have succeeded or not. If it was it contains value, if not it contains error. If we query our database for a client by client id and no record is found, what should we return? Null you would say, or maybe throw an exception? We can return Result of that operation, that if client was found contains Client object and if not it contains Error saying that entity was not found. Consumer of that operation now has to check if it was successful and then use its value or failure and he can handle error properly. And again we gain:
- readability – you indicate that this operation may fail in some cases
- avoiding nulls
- proper error handling
Do you feel like this does not belong to C# world? You might be using monads on daily basis… IEnumerable, Nullable. Functional programing is where it used to belong, but as many things it’s soaking into object oriented programming. You can check my implementation of Result monad in C# on my github.