Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relationship between Functor, Applicative Functor, and Monad

Tags:

haskell

When reading up on type classes I have seen that the relationship between Functors, Applicative Functors, and Monads is that of strictly increasing power. Functors are types that can be mapped over. Applicative Functors can do the same things with certain effects. Monads the same with possibly unrestrictive effects. Moreover:

Every Monad is an Applicative Functor
Every Applicative Functor is a Functor

The definition of the Applicative Functor shows this clearly with:

class Functor f => Applicative f where
  pure  :: a -> f a
  (<*>) :: f (a -> b) -> f a -> f b

But the definition of Monad is:

class Monad m where
  return :: a -> m a
  (>>=)  :: m a -> (a -> m b) -> m b
  (>>)   :: m a -> m b -> m b
  m >> n = m >>= \_ -> n
  fail   :: String -> m a

According to Brent Yorgey's great typeclassopedia that an alternative definition of monad could be:

class Applicative m => Monad' m where
  (>>=) :: m a -> (a -> m b) -> m b

which is obviously simpler and would cement that Functor < Applicative Functor < Monad. So why isn't this the definition? I know applicative functors are new, but according to the 2010 Haskell Report page 80, this hasn't changed. Why is this?

like image 689
Magnus Kronqvist Avatar asked Dec 28 '11 16:12

Magnus Kronqvist


People also ask

What is the difference between functor and 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). Hence you can chain two monads and the second monad can depend on the result of the previous one.

Is applicative a functor?

Applicative functors are the programming equivalent of lax monoidal functors with tensorial strength in category theory. Applicative functors were introduced in 2008 by Conor McBride and Ross Paterson in their paper Applicative programming with effects.

Are all monads applicative?

Monads are not a replacement for applicative functors Instead, every monad is an applicative functor (as well as a functor). It is considered good practice not to use >>= if all you need is <*>, or even fmap.

Is functor a Typeclass?

The Functor typeclass represents the mathematical functor: a mapping between categories in the context of category theory. In practice a functor represents a type that can be mapped over.


2 Answers

Everyone wants to see Applicative become a superclass of Monad, but it would break so much code (if return is eliminated, every current Monad instance becomes invalid) that everyone wants to hold off until we can extend the language in such a way that avoids breaking the code (see here for one prominent proposal).

Haskell 2010 was a conservative, incremental improvement in general, standardising only a few uncontroversial extensions and breaking compatibility in one area to bring the standard in line with every existing implementation. Indeed, Haskell 2010's libraries don't even include Applicative — less of what people have come to expect from the standard library is standardised than you might expect.

Hopefully we'll see the situation improve soon, but thankfully it's usually only a mild inconvenience (having to write liftM instead of fmap in generic code, etc.).

like image 160
ehird Avatar answered Oct 06 '22 06:10

ehird


Changing the definition of Monad at this point, would have broken a lot of existing code (any piece of code that defines a Monad instance) to be worthwhile.

Breaking backwards-compatibility like that is only worthwhile if there is a large practical benefit to the change. In this case the benefit is not that big (and mostly theoretical anyway) and wouldn't justify that amount of breakage.

like image 31
sepp2k Avatar answered Oct 06 '22 07:10

sepp2k