25

I'm looking for the following function:

Applicative f => f (f a) -> f a

Hoogle shows me join:

>:t join
join :: Monad m => m (m a) -> m a

Is there a function that matches my desired signature?

JJJ
  • 32,902
  • 20
  • 89
  • 102
Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384
  • Possible duplicate of [What advantage does Monad give us over an Applicative?](http://stackoverflow.com/questions/17409260/what-advantage-does-monad-give-us-over-an-applicative) –  Oct 15 '15 at 20:01

3 Answers3

51

To expand a bit on Carl's answer, If there was such a thing as join, but for applicatives:

class Applicative f => ApplicativeWithJoin f where
    join' :: f (f a) -> f a

Then you would automatically have a monad:

instance ApplicativeWithJoin m => Monad m where
    return = pure
    x >>= f = join' (f <$> x)
Community
  • 1
  • 1
SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
46

There is no such function. join is explicitly what Applicative lacks and Monad has.

Carl
  • 26,500
  • 4
  • 65
  • 86
8

To expand on SingleNegationElimination's answer:

  • Applicative's <*> allows you to combine effects together and their values inside together, or manipulate a value inside using <$>, but you can't make an effect depend on a value of a previous computation.
  • Monads, on the other hand, allow an effect to be determined by the result of the previous computation, as witnessed by >>=.

With any Applicative you can first use <$> to convert a value of type a inside f a into some f b, so you'll get f (f b). But without join, the inner f b is just another value, there is no way how you can combine it with the outer one that is actually executed. Adding join makes it possible, allowing to define the full power of Monad.

Petr
  • 62,528
  • 13
  • 153
  • 317