Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the 'minimum' needed to make an Applicative a Monad?

The Monad typeclass can be defined in terms of return and (>>=). However, if we already have a Functor instance for some type constructor f, then this definition is sort of 'more than we need' in that (>>=) and return could be used to implement fmap so we're not making use of the Functor instance we assumed.

In contrast, defining return and join seems like a more 'minimal'/less redundant way to make f a Monad. This way, the Functor constraint is essential because fmap cannot be written in terms of these operations. (Note join is not necessarily the only minimal way to go from Functor to Monad: I think (>=>) works as well.)

Similarly, Applicative can be defined in terms of pure and (<*>), but this definition again does not take advantage of the Functor constraint since these operations are enough to define fmap.

However, Applicative f can also be defined using unit :: f () and (>*<) :: f a -> f b -> f (a, b). These operations are not enough to define fmap so I would say in some sense this is a more minimal way to go from Functor to Applicative.

Is there a characterization of Monad as fmap, unit, (>*<), and some other operator which is minimal in that none of these functions can be derived from the others?

  • (>>=) does not work, since it can implement a >*< b = a >>= (\ x -> b >>= \ y -> pure (x, y)) where pure x = fmap (const x) unit.
  • Nor does join since m >>= k = join (fmap k m) so (>*<) can be implemented as above.
  • I suspect (>=>) fails similarly.
like image 839
Nick Rioux Avatar asked Nov 19 '20 22:11

Nick Rioux


People also ask

Is every monad applicative?

Monads are not a replacement for applicative functors Instead, every monad is an applicative functor (as well as a functor).

What is applicative monad?

An applicative is a data type that implements the Applicative typeclass. A monad is a data type that implements the Monad typeclass. A Maybe implements all three, so it is a functor, an applicative, and a monad.

Is every functor a monad?

As I understand, every monad is a functor but not every functor is a monad. A functor takes a pure function (and a functorial value) whereas a monad takes a Kleisli arrow, i.e. a function that returns a monad (and a monadic value).

What is an applicative functor in Haskell?

In Haskell, an applicative is a parametrized type that we think of as being a container for data of that type plus two methods pure and <*> . Consider a parametrized type f a . The pure method for an applicative of type f has type. pure :: a -> f a. and can be thought of as bringing values into the applicative.


1 Answers

I have something, I think. It's far from elegant, but maybe it's enough to get you unstuck, at least. I started with join :: m (m a) -> ??? and asked "what could it produce that would require (<*>) to get back to m a?", which I found a fruitful line of thought that probably has more spoils.

If you introduce a new type T which can only be constructed inside the monad:

t :: m T

Then you could define a join-like operation which requires such a T:

joinT :: m (m a) -> m (T -> a)

The only way we can produce the T we need to get to the sweet, sweet a inside is by using t, and then we have to combine that with the result of joinT somehow. There are two basic operations that can combine two ms into one: (<*>) and joinT -- fmap is no help. joinT is not going to work, because we'll just need yet another T to use its result, so (<*>) is the only option, meaning that (<*>) can't be defined in terms of joinT.

You could roll that all up into an existential, if you prefer.

joinT :: (forall t. m t -> (m (m a) -> m (t -> a)) -> r) -> r
like image 139
luqui Avatar answered Sep 28 '22 05:09

luqui