# Staring at (\$), (<\$>), (<*>) and (>>=)

Posted on February 18, 2020 by Riccardo.

Recently I’ve spent some time staring at type signatures. The goal was to develop a better intuition by absorbing their wisdom. Last week it was Monad’s `bind`. This time I’ve decided to compare the following four:

``````(\$)   ::   (a ->   b) ->   a ->   b
(<\$>) ::   (a ->   b) -> f a -> f b
(<*>) :: f (a ->   b) -> f a -> f b
(>>=) ::   (a -> m b) -> m a -> m b``````

## Function Application or `(\$)`

``(\$) :: (a -> b) -> a -> b``

It takes a funtion from a value of type `a` to a value of type `b`, an `a` and returns `b`. There’s only one possible way to implement `(\$)` which is to apply the funtion to the value of type `a`.

## Functor’s `fmap` or `(<\$>)`

``(<\$>) :: (a -> b) -> f a -> f b``

The only difference from the previous is that `a` and `b` exist in a context `f`. For example, we could have an `Int` in a `List` context (i.e. `[Int]`), which means we went from one `Int` to any number of `Int`s. Or we could have an `Int` in a `Maybe` context (i.e. `Maybe Int`), in other words there could be either no `Int`s or just one `Int`. And so on and so forth depending on the semantics of each functor.

Again, it’s easy to see how the value of type `a` must feed the function from `a` to `b` to generate the output. The only difference from `(\$)` is that depending on the semantics of the context `f`, the function will be applied in a different way.

## Applicative Functor’s sequential application or `(<*>)`

``(<*>) :: f (a -> b) -> f a -> f b``

In this instance, the function from `a` to `b` has a context `f` too. Therefore, the way the output is calculated depends on both the first and the second `f` (which must be the same `f`).

## Monad’s `bind` or `(>>=)`

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

This time, the way the function is applied depends only on the second `m`. This is the same situation as for `(<\$>)`. But there’s one important change: the previous functions could only transform an `a` into a `b`. In the case of `bind`, the funtion decides not only on the `b` but also on the `m`, which must be the same `m` for both.

## Concretely

Let’s see the above in action in the context of `Either` which has an instance for Functor, Applicative Functor and Monad. Notice that the instances are defined for `Either e` because the context they provide is around one type, not two. For example, given an `Int` we can provide it an `Either String` context by doing `Either String Int`.

``````show 1
--> "1"

-- (\$)

show \$ 1
--> "1"

-- (<\$>)

show <\$> Right 1
--> Right "1"

show <\$> Left "string"
--> Left "string"

-- Either maps the function only when the value is a `Right`.

-- (<*>)

Right show <*> Right 1
--> Right "1"

Right show <*> Left "string"
--> Left "string"

Left show <*> Right 1
--> Left show

Left show <*> Left "string"
--> Type error: the type on the left should be the same for both `Either`s.

-- Either applies the function only when both values are `Right`.

-- (>>=)

Right 1 >>= (\x -> Right (show x))
--> Right "1"

Left "string" >>= (\x -> Right (show x))
--> Left "string"

Right 1 >>= (\x -> Left (show x))
--> Left "string"

Left "string" >>= (\x -> Left (show x))
--> Left "string"

-- Either binds the function only when the value before `>>=` is a `Right`.
-- Contrarily to the previous cases, `>>=` can decide to return `Left` or `Right`.``````

I need your help to make the blog awesome. Here's a survey. Since there are no required questions, you decide how much time to spend on it.