A side effect is an observable interaction with its environment (apart from computing its result value). In Haskell, we try hard to avoid functions with such side effects. This even applies to `IO`

actions: when an `IO`

action is evaluated, no side effects are performed, they are executed only when the actions prescribed in the `IO`

value are executed within `main`

.

However, when working with abstractions that are related to composing computations, such as applicative functors and monads, it’s convenient to somewhat distinguish between the actual value and the “rest”, which we often call an “effect”. In particular, if we have a type `f`

of kind `* -> *`

, then in `f a`

the `a`

part is “the value” and whatever “remains” is “the effect”.

I intentionally quoted the terms, as there is no precise definition (as far as I know), it’s merely a colloquial definition. In some cases there are no values at all, or multiple values. For example for `Maybe`

the “effect” is that there might be no value (and the computation is aborted), for `[]`

the “effect” is that there are multiple (or zero) values. For more complex types this distinction can be even more difficult.

The distinction between “effects” and “values” doesn’t really depend on the abstraction. `Functor`

, `Applicative`

and `Monad`

just give us tools what we can do with them (`Functor`

s allow to modify values inside, `Applicative`

s allow to combine effects and `Monad`

s allow effects to depend on the previous values). But in the context of `Monad`

s, it’s somewhat easier to create a mental picture of what is going on, because a monadic action can “see” the result value of the previous computation, as witnessed by the

```
(>>=) :: m a -> (a -> m b) -> m b
```

operator: The second function receives a value of type `a`

, so we can imagine “the previous computation had some effect and now there is its result value with which we can do something”.