# Understanding IO Monad in Scala

Hey guys!

In my last post, we discussed how to set up a simple REST service in Scala, wherein we used cats-effect **IO Monad** to wrap our ** effect-ful** (or you can say

**) code to ensure it remains functionally pure (referentially transparent).**

*side-effect-ing*Now anyone new to the Functional Programming world will be swarming with questions such as:

- What are side-effects and Referential Transparency?
- How does it affect my code?
- What is this IO Monad you are talking about? and How does it magically fixes my code?

At least, these were the question I had when I first encountered the IO monad. So, I thought I should put up a little something for anyone having the above questions.

Now, let’s go for it!

**What is an effect/side-effect?**

A side-effect is a function/expression which changes/mutates the state of something outside its local environment.

It can be something as simple as printing to console, making a DB call or a file read/write operation.

Before we go ahead, let me introduce you to ** Referential Transparency**.

By definition, it is a property of purely functional languages that says an expression always gets evaluated to the same result, and that the expression itself can be replaced by its result without changing the behavior of the program.

You might think, what’s new about it, the below expressions:

and

are *equivalent* and hence *referentially transparent*.

Well, the problem starts when we have these ** side-effects** involved in our code.

Let’s say we have defined a function *demo:*

This function takes in 2 arguments of type Unit and performs no computation. Now, we have the *effect-ful*** computation** stored in variable

**, and we then call the function demo:**

*val x*You will observe that the above computation prints “Hello World !” on the console **ONCE**.

Now, let’s replace ** x** in the function call with its value:

“Hello World !” gets printed on the console **TWICE**.

This clearly ** violates** the rule of referential transparency.

*We got different behavior from the same function when we replace the expression by its value*.

**So, How can we ensure referential transparency in our program?**

The current state of our code is, if we write an effect-ful expression:

The runtime just evaluates the side-effect (read eager evaluation), without giving us any chance to stop that from happening or manipulating it.

The solution to our problem comes with the ability to ** control** WHEN these effects get

**.**

*evaluated*This is where the **IO Monad** comes in. The IO Monad can be thought of as a ** wrapper around these effects**, which provides us the ability to evaluate them when we need to. We’ll be using the cats-effect library in this post to demonstrate the use of IO Monad.

So let’s say we have a side-effecting function, *toConsole* :

We can be very sure that whenever we call the above function, we’ll always get the ** input** String printed on the console, as it gets evaluated eagerly.

We’ll now use the cats-effect IO, to wrap this side-effect.

Now, what happens when we call this function?

*Absolutely Nothing !!*

Yes, nothing gets printed to the console. This is because, the return type of the function is now **IO[Unit]**, our side-effecting code is now wrapped inside the IO and cannot evaluate unless and until we tell it so.

Cats IO provides us the method ** unsafeRunSync()** to evaluate the encapsulated code. So to make it run we can:

Now, we can make our previous example referentially transparent as well, using our newly gained knowledge of the IO monad.

To understand IO Monad, we need to take a look at what a **Monad** is.

Monad is an ADT (Algebraic Data Type) that has 2 functions:

- A unit function used to place a value into the monad.
- A composition function that composes 2 monads.

(This is by no means a complete definition to a Monad, refer to this awesome video if you want to dig deep)

The representation of Monad in Scala is:

To understand this better, let’s take an example of Scala’s own ** Option[A]** monad, and its subtypes:

**&**

*Some[A]***.**

*None*The **Option[A]** returns **Some[A]** if A is not Null, and return **None** if A is Null.

To make this more clear let's have a function ** mayReturnString **which returns an

**:**

*Option[String]*Here ** mayReturnString **can either be

**or**

*None***but thanks to Option we don’t need to do any checks.**

*Some(“demo string”)*What’s more, we can even transform the values as we require using ** map / flatMap**:

And as you can see, we transformed the type ** Option[String] — > Option[Int]**, without actually doing any checks for Null values, hence making our code more expressive.

So, **What is an IO Monad?**

IO Monad is simply a Monad which:

- Allows you to safely manipulate effects
- Transform the effects into data and further manipulate it before it actually gets evaluated.

As a side-note, the Monad also ** guarantees sequential evaluation** during the composition of 2 monads.

Observe the definition of the composition function:

in the function ** f: A => F[B]**, we need the value of type A to transform it into F[B], which mandates that the evaluation of F[A] will be done before evaluation of F[B] because F[B] won’t even exist by then.

This property enables us to manipulate multiple side-effect-ing code, with the control of having them execute sequentially.

At last, we’ll take a look at an example, which copies the contents of one File to another. Firstly, let's define a dummy implementation of the ** read** and

**functions for file operations:**

*write*Now, using ** for-comprehension** we can write the function to copy the content as:

And we can be absolutely sure that the evaluation of ** read()** will always happen before the evaluation of

**.**

*write()*I hope I was able to draw a clear picture of what the IO Monad is, why it's needed and how it works.

There is much more to Cat’s IO, but I think this is enough to get you started.