[Haskell-cafe] Another point-free question (>>=, join, ap)

Jonathan Cast jonathanccast at fastmail.fm
Thu Feb 12 18:59:06 EST 2009

```On Thu, 2009-02-12 at 23:36 +0000, Edsko de Vries wrote:
> Hi,
>
> I can desugar
>
>   do x' <- x
>      f x'
>
> as
>
>   x >>= \x -> f x'
>
> which is clearly the same as
>
>   x >>= f
>
> However, now consider
>
>   do x' <- x
>      y' <- y
>      f x' y'
>
> desugared, this is
>
>   x >>= \x -> y >>= \y' -> f x' y'
>
> I can simplify the second half to
>
>   x >>= \x -> y >>= f x'
>
> but now we are stuck. I feel it should be possible to write something like
>
>   x ... y ... f
>
> or perhaps
>
>   f ... x ... y
>
> the best I could come up with was
>
>   join \$ return f `ap` x `ap` y
>
> which is not terrible but quite as easy as I feel this should be. Any hints?

Copying a bit of Applicative style, you could say

join \$ f `liftM` x `ap` y

I've thought it would be nice to have something like

app :: Monad m => m (a -> m b) -> m a -> m b
app af ax = join \$ af `ap` ax

in the standard library.  Then you could simplify to

f `liftM` x `app` y

I think that's as simple as you're going to get.  For more arguments,
say

f `liftM` x `ap` y `app` z

The rule is: first application operator is `liftM` (or <\$> --- I always
define Applicative instances for my monads); last application operator
is `app`; the operators in-between are all `ap`.  I think that's a
pretty straight-forward rule to follow.

jcc

```