Skip to main content

Monad: in programming

Monad is a structure with type constructor M and two functions unit (η) and multiplication (μ).


and

 

To lift value from a to Ma we need unit function and to flatten from M(Ma) to Ma we need multiplication.

Why do we need monad in functional programming? Why do we need functional programming anyways?

Functional programming is a paradigm which uses pure functions to build an application. The power of pure functions are, we can compose them and we can build complex things out of the small and simple functions.

If we have these functions

 

and

 

We can get

 

We can use below general purpose compose function to compose any two pure functions.

 

If we need to compose three functions then we can do like

Now, we can't build application using only pure functions. It is next to impossible. We need side effects anyways to make the application practical in use. To achieve the goal, we need to keep pure functions in center/core part of application and need to move side effects outside of core layer as much as possible.

How can we achieve this?

Side effects may occur at any part of application. (e. g. console log, taking input from user, writing/reading files, sending/receiving data to/from network, handling future value (asynchronous scenario), handling errors etc.)

As pure function returns same exact value for  particular input values always, pure function can't stay pure if it tries to handle any of the above scenario.

Suppose, we have a function below, it throws error if value is zero.


This is not a pure function as it has side effect. How can we make it pure and can delay or wrap the side effect and move it to outer layer of application?

We have used Either here. Either is a monad. We wrapped success and failure both case in same monad. So, our function will always return the Either in both of the scenario. It became pure now. 

If we do not use Either we need to handle error right away or need to throw error again which does not make any function pure and increases code complexity too.


If we use Either we can handle the error later. 

This way we are moving side effects to outer layer as much as possible and  trying to make function pure in core code.

Did you notice map function in code? Functor has map function, and monad is a functor too, so lets take a brief introduction of functor.

Functor lifts values and functions between those values.

If we have function

then functor F lifts a to Fa, b to Fb and f to Ff. This way, we have another function like,

To get the new function Ff we can reuse original function f, the Ff can be called map too.

 

Functor has limitation. It just lifts values and functions, it can't unlift or flatten it. That is where monad comes into picture. Lets continue with monad.

Function which returns monadic value looks like this.

So, if we want to compose functions which returns monadic value we can do this.

But, wait... Before, it was straightforward, we have b from first function and need to pass the same b to second one. How can we convert Mb to b, and make the functions composable.

We need to define an extra function to make this whole expression looks like compose.

The extra function is

Notice that this is multiplication or μ (can be called flatten or join too).

So, including the above function in normal compose, we can make functions returning monadic value composable.

There is another  function we need to pay some attentions to it is..

This is not the same as 


But, as monad is a functor too.  We can find the map for above scenario as..

So, new compose will become like..


To make composition work we introduce two functions map and flatten here. As composition always evaluates in revers order, we can call combined function of these both as flatMap. If you ever worked with monad you can recall flatMap.

Now, we can create pure functions hiding / delaying side effects and we can compose that functions as well.

We have type constructor M, so it is good to define a function which can accept value, lifts it (using type constructor) and returns monadic value.

This is called unit or η (can be called return too).

If we describe monad very simply than.. 

Monad is a container / context / structure for value with type constructor M, and functions unit and multiplication.

This is very basic and summarized  article of monad.

We will see complex and in-depth understanding of monad using category theory in next article.

Comments

Popular posts from this blog

Basics of quantum computing: change of basis

Computing requires classical bits, which can hold a value of 0 or 1. Quantum computing gets benefit from superposition of quantum bit (qubit). Qubit is a representation of state of quantum object (electron, proton, photon, etc). The qubit holds a value between 0 and 1 while it is in superposition state. Superposition means the qubit possesses multiple values at the same time so we can harness its power for parallel computing. Once we try to measure the value it can be collapsed into either 0 or 1 based on probability. (Observer collapses wave function simply by observing.) Using bloch sphere, we can represent qubit physically. (The bloch sphere is a physical model to represent a spin state of qubit) A state vector can point to any direction from the center of the sphere. If a vector points to Z+ and Z-, it represents 0 and 1 state respectively. All other vectors represent superposition state in a Z basis. Now, if a vector points to X+, X-, Y+, Y-, all are at a 90-degree angle from

Monad: to programming from category theory

We have seen the summarized article "monad in programming" in the previous post. Let's find out what is a monad in category theory and how the concept became relevant for functional programming. First, we need to understand the basics of category theory. Category A category consists of objects and morphisms (relationships) between those objects. More of it, the morphisms should be composable too. Below is an example of a category. Each dot is an object and each arrow shows morphism from some object to another. As arrows are composable, if there is a morphism from object a to object b , and there is another morphism from b to c , then we can find a morphism from a to c .  If you notice, there is identity morphism too, it exists for each object, but we have shown it just for x . It is a morphism from an object to itself. If we compose identity morphism with any other morphism w , we get the same w in return. Functor A functor is a relationship between categories