## Missed optimization

## Motivation

When compiling the function below:

```
myJoin :: Monad m => m (m a) -> m a
myJoin mma =
do
ma <- mma
a <- ma
return a
```

ghc generates two calls to the bind function (just as the code specifies). But this function is (I believe) semantically equivalent to the following:

```
myJoin' :: Monad m => m (m a) -> m a
myJoin' mma =
do
ma <- mma
ma
```

which could potentially be more efficient since only one bind is performed. Perhaps ghc could be taught to perform this transformation.

For an even simpler example consider:

```
silly_1 :: Monad m => m a -> m a
silly_1 ma =
do
a <- ma
return a
silly_2 :: Monad m => m a -> m a
silly_2 ma = do ma
silly_3 :: Monad m => m a -> m a
silly_3 ma = ma
```

Here ghc realizes that (2) and (3) are the same function (aka the identity function) but it compiles (1) with a call to bind.

```
silly_1
= \ (@ (m_a76C :: * -> *))
(@ a_a76D)
($dMonad_a76F :: Monad m_a76C)
(ma_a5Vu :: m_a76C a_a76D) ->
>>=
@ m_a76C
$dMonad_a76F
@ a_a76D
@ a_a76D
ma_a5Vu
(\ (a1_a5Vv :: a_a76D) ->
return @ m_a76C $dMonad_a76F @ a_a76D a1_a5Vv)
silly_2
= \ (@ (m_ankf :: * -> *))
(@ a_ankg)
_ [Occ=Dead]
(ma_an0P :: m_ankf a_ankg) ->
ma_an0P
silly_3 = silly_2
```

This is all with ghc 8.8.4.

## Proposal

Teach ghc to perform this transformation.