The identity monad can be seen as the ambient monad that encodes the
effect of having no effect. It is ambient in the sense that plain pure
values are values of `Id`

.

It is encoded as:

`type Id[A] = A`

That is to say that the type Id[A] is just a synonym for A. We can
freely treat values of type `A`

as values of type `Id[A]`

, and
vice-versa.

```
import cats._
val x: Id[Int] = 1
val y: Int = x
```

We can freely compare values of `Id[T]`

with unadorned
values of type `T`

.

```
val anId: Id[Int] = 42
anId should be(res0)
```

Using this type declaration, we can treat our Id type constructor as a
`Monad`

and as a `Comonad`

. The `pure`

method, which has type `A => Id[A]`

just becomes the identity
function. The `map`

method from `Functor`

just becomes function
application:

```
import cats.Functor
val one: Int = 1
Functor[Id].map(one)(_ + 1)
```

`Applicative[Id].pure(42) should be(res0)`

Compare the signatures of `map`

and `flatMap`

and `coflatMap`

:

```
def map[A, B](fa: Id[A])(f: A => B): Id[B]
def flatMap[A, B](fa: Id[A])(f: A => Id[B]): Id[B]
def coflatMap[A, B](a: Id[A])(f: Id[A] => B): Id[B]
```

You'll notice that in the flatMap signature, since `Id[B]`

is the same
as `B`

for all B, we can rewrite the type of the `f`

parameter to be
`A => B`

instead of `A => Id[B]`

, and this makes the signatures of the
two functions the same, and, in fact, they can have the same
implementation, meaning that for `Id`

, `flatMap`

is also just function
application:

```
import cats.Monad
val one: Int = 1
Monad[Id].map(one)(_ + 1)
Monad[Id].flatMap(one)(_ + 1)
```

```
val fortytwo: Int = 42
Comonad[Id].coflatMap(fortytwo)(_ + 1) should be(res0)
```