Haskell - is there extended monad type [ m (a -> m b) -> m a -> m b ]

Viewed 183

Functor has

(a -> b) -> m a -> m b

Applicative has

f (a -> b) -> f a -> f b

Monad has

m a -> (a -> m b) -> m b

But, Is there extended monad type that has

m a -> m (a -> m b) -> m b

or

m (a -> m b) -> m a -> m b

?

1 Answers

A Monad constraint is sufficient to implement a (sensible) function with that type signature:

foo :: Monad m => m (a -> m b) -> m a -> m b
foo mf ma = do
   f <- mf
   a <- ma
   f a

or, if you prefer:

foo' :: Monad m => m (a -> m b) -> m a -> m b
foo' mf ma = mf >>= \f -> ma >>= f

This means that your proposed operation, even though it looks like a generalization of the usual >>= bind operation, isn't actually a generalization. Any >>= operation can be written in terms of foo, and any foo operation can be written in terms of >>=, so they are operations of equivalent "power".

In contrast, the other operations are not of equivalent power. Any applicative operation <*> can be written in terms of >>= and return, but you can't in general implement >>= in terms of <*>, so >>= is a strictly more powerful operation, etc.

Related