join определяется вместе с bind, чтобы сгладить объединенную структуру данных в единую структуру.
Из системного представления типа (+) 7 :: Num a => a -> a можно рассматривать как Functor, (+) :: Num a => a -> a -> a можно рассматривать как Functor of Functor, как получить некоторую интуицию об этом, а не просто полагаться на систему типов? Почему join (+) 7 === 14?
Несмотря на то, что можно получить окончательный результат путем ручного перехода по процессу связывания функции, было бы здорово, если бы была указана какая-то интуиция.
Это из упражнений NICTA.
-- | Binds a function on the reader ((->) t).
--
-- >>> ((*) =<< (+10)) 7
-- 119
instance Bind ((->) t) where
  (=<<) ::
    (a -> ((->) t b))
    -> ((->) t a)
    -> ((->) t b)
  (f =<< a) t =
    f (a t) t
-- | Flattens a combined structure to a single structure.
--
-- >>> join (+) 7
-- 14
join ::
  Bind f =>
  f (f a)
  -> f a
join f =
  id =<< f
*Course.State> :t join (+)
join (+) :: Num a => a -> a
*Course.State> :t join
join :: Bind f => f (f a) -> f a
*Course.State> :t (+)
(+) :: Num a => a -> a -> a