5

I'm looking for a function or operator in Haskell that is effectively a Monad equivalent of the Applicative operator <*> that applies a monadic action rather than a bare function, that is instead of this:

(<*>) :: Applicative f => f (a -> b) -> f a -> f b

I'm looking for something that looks like this:

... :: Monad m => m (a -> m b) -> m a -> m b

I can't believe that this isn't a standard function, but I can't see anything that matches. Am I missing something?

Jules
  • 14,841
  • 9
  • 83
  • 130

1 Answers1

6

This will be a simple composition of two other basic monad functions, namely join and ap; since:

ap :: Monad m => m (a -> b) -> m a -> m b
join :: Monad m => m (m a) -> m a

we get:

(join .) . ap :: Monad m => m (a -> m b) -> m a -> m b

as well as:

(join .) . (<*>) :: Monad m => m (a -> m b) -> m a -> m b

or, using only bind operator, another construct would be:

(. (>>=)) . (>>=) :: Monad m => m (a -> m b) -> m a -> m b
behzad.nouri
  • 74,723
  • 18
  • 126
  • 124
  • What is `(join .)`? – Kamel Jun 18 '16 at 23:51
  • 1
    @Kamel `join` applied to composition operator: `(join .) :: Monad m => (a -> m (m a1)) -> a -> m a1` – behzad.nouri Jun 18 '16 at 23:54
  • Thank you. I forgot `(.)` is an operator. :) – Kamel Jun 19 '16 at 00:09
  • 2
    @Kamel `((f .) . g) x y = f (g x y)`. – Will Ness Jun 19 '16 at 00:15
  • @behzad.nouri How could the type of `(join .)` be deduced? I am not able to connect `(.):: (b -> c) -> (a -> b) -> a -> c` to the input of `join` which is `m (m a)`. Even though I know `(->) a` is a functor. – Kamel Jun 19 '16 at 01:07
  • 1
    @Kamel see e.g. http://stackoverflow.com/questions/13139969/currying-3-arguments-in-haskell/13147064#13147064 and [tag:pointfree] in general. And [tag:type-inference] for the type inference stuff, e.g. http://stackoverflow.com/questions/14335704/haskell-how-to-infer-the-type-of-an-expression-manually. – Will Ness Jun 19 '16 at 01:23
  • 1
    And [tag:type-inference] for the type inference stuff, e.g. http://stackoverflow.com/questions/14335704/haskell-how-to-infer-the-type-of-an-expression-manually. --- `(join .)` is an operator section, same as `(.) join`. – Will Ness Jun 19 '16 at 01:28