Monads in Functional Programming

The idea of doing a computation within a special context isn't unique to quantum computing. Functional programming has a concept called the monad that does something similar. This is how it works: you have an input value and you want to perform a sequence of calculations within a certain special context. So you take that value, wrap it up inside an object called as a monad, and do the sequence of operations using the monad object to preserve the context. Once the calculation is done, you get the final output out from the monad.

That sounds quite abstract, so let us take a concrete example.

Suppose we want to do a sequence of calculations:

  1. Get a number from a list
  2. Call a function that will perform some operation on the number (for this example, let us say it doubles the input number)
  3. Put the answer into another list

That would be quite simple. We might have three functions get_num, do_op, save_num that do each of those steps individually, and we can combine them by passing the output of the first function to the second, and output of the second to the third. The code in python would look something like this: save_num(do_op(get_num()))

Now, lets add a wrinkle into the requirements. Lets say get_num actually hits a database to get the number, do_op performs the operation via a network API and save_num saves it back into a database. You might have realised that any of the three functions could fail. The function signature needs to include a bool signalling whether ther operation was a success. The return value of the function changes from get_num() -> int to get_num() -> tuple[bool, int]

It also means that we can no longer just chain the output of one to the input of the next function, since the next function requires int as input, not tuple[bool, int]

Monads are a solution to this. The monad for this problem is called the Maybe monad. By wrapping the value in monad, we can do the entire calculation without worrying about the possibility that any of the functions in the computation might fail. At the end of the computation we can unwrap the value from the monad, see whether there were any failures, and get the answer if the entire computation chain was successful. For a detailed write up on how it works, check out my article on the playful python site: