- A+

I would prefer defining an instance of Monad via the join function instead of >>= ... Starting from that equivalence :

`x >>= f = join (fmap f x) `

so you could define a Monad instance only with join.

I would have expected join in Monad with : `{-# MINIMAL (>>=)| join #-}`

Why is `join`

at the top level and not even in the `Monad`

typeclass?

Sadly, `join`

is not a part of the `Monad`

typeclass in GHC’s standard library because of technical restrictions related to generalized newtype deriving and the roles system. Long story short, given some newtype `newtype T m a = MkT (m a)`

, GHC is not smart enough to figure out how to prove representational equality between `m (m a)`

and `m (T m a)`

, which is necessary for proving representational equality for the first argument of `join`

(which has type `m (m a) -> m a`

).

Fortunately, a recent extension to GHC Haskell, `QuantifiedConstraints`

, might make it possible to make the roles system smart enough to support this. For a more detailed treatment of both the problem and its potential solution, see Ryan Scott’s blog post, How QuantifiedConstraints can let us put join back in Monad.