join is just implemented as [src]:
join              :: (Monad m) => m (m a) -> m a
join x            =  x >>= id
If we take a look at the monad instances of [] [src] and Maybe [src], we see:
instance Monad []  where
    {-# INLINE (>>=) #-}
    xs >>= f             = [y | x <- xs, y <- f x]
    {-# INLINE (>>) #-}
    (>>) = (*>)
    {-# INLINE fail #-}
    fail _               = []
instance  Monad Maybe  where
    (Just x) >>= k      = k x
    Nothing  >>= _      = Nothing
    (>>) = (*>)
    fail _              = Nothing
So that means that for lists, join is equivalent to:
-- for lists
   join xs
-> xs >>= id
-> [ y | x <- xs, y <- id x ]
-> concatMap id xs
-> concat xs
so for lists, the equivalent implementation is:
join_list :: [[a]] -> [a]
join_list = concat
For Maybe we can do case-analysis: the input is a Maybe (Maybe a) so there are basically three possibilities here:
-- (1)
   join Nothing
-> Nothing >>= id
-> Nothing
-- (2)
   join (Just Nothing)
-> Just Nothing >>= id
-> id Nothing
-> Nothing
-- (3)
   join (Just (Just x))
-> Just (Just x) >>= id
-> id (Just x)
-> Just x
So that means that for Maybes the equivalent implementation is:
join_maybe :: Maybe (Maybe a) -> Maybe a
join_maybe (Just x) = x
join_maybe Nothing = Nothing
join is thus not reimplemented for list or Maybe monads, it simply uses the implementation for (>>=) for lists and Maybes, and since these differ, the behavior of join is of course different.