The 
join function is the conventional monad join operator. It
is used to remove one level of monadic structure, projecting its bound
argument into the outer level.
'
join bss' can be understood as the 
do
expression
do bs <- bss
bs
Examples
>>> join [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[1,2,3,4,5,6,7,8,9]
>>> join (Just (Just 3))
Just 3
A common use of 
join is to run an 
IO computation
returned from an 
STM transaction, since 
STM transactions
can't perform 
IO directly. Recall that
atomically :: STM a -> IO a
is used to run 
STM transactions atomically. So, by specializing
the types of 
atomically and 
join to
atomically :: STM (IO b) -> IO (IO b)
join       :: IO (IO b)  -> IO b
we can compose them as
join . atomically :: STM (IO b) -> IO b
to run an 
STM transaction and the 
IO action it returns.