Studying functors, applicative functors and monads in Haskell, I found this definition on Wikipedia:
In functional programming, specifically Haskell, an applicative functor is a structure that is like a monad (
return
,fmap
,join
) withoutjoin
, or like a functor withreturn
.
I can't understand: it seems to me that providing return
(i.e. pure
) to a functor is not sufficient to obtain an applicative functor, because you need to provide ap
(i.e. <*>
) too, which cannot be defined in terms of fmap
and return
only. Did I miss something or Wikipedia's definition is not absolutely correct?
EDIT 2017-02-08: I found other useful insights on this question in this answer.
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.
Functor in Haskell is a kind of functional representation of different Types which can be mapped over. It is a high level concept of implementing polymorphism. According to Haskell developers, all the Types such as List, Map, Tree, etc. are the instance of the Haskell Functor.
A functor is an interface with one method i.e a mapping of the category to category. Monads basically is a mechanism for sequencing computations. A monad is a way to wrap stuff, then operate on the wrapped stuff without unwrapping it.
Functor in Haskell is a typeclass that provides two methods – fmap and (<$) – for structure-preserving transformations. To implement a Functor instance for a data type, you need to provide a type-specific implementation of fmap – the function we already covered.
The article was not correct. Assume we have a monad m
without join
, or a functor with return
. We can define pure
immediately:
pure :: Monad m => a -> m a
pure = return
We cannot, however, define (<*>)
with fmap
and return
only. All we have is fmap
, so we would end up with m (m a)
if we try to use an m (a -> b)
. At that point we need join
or its equivalent (>>=)
:
(<*>) :: Monad m => m (a -> b) -> m a -> m b
f <*> x = join (fmap (flip fmap x) f)
-- or, easier to read:
-- f <*> x = do
-- f' <- f
-- x' <- x
-- return f' x'
An applicative functor is like a functor with return
and ap
, but no join
. So yes, you were completely right, Wikipedia missed the operation of applicative (see the original paper).
By the way, if you add only pure
, you get a pointed functor. The typeclassopedia provides a better overview over Applicative
than the Wikipedia article, though.
You are correct, applicative functors require <*>
as well as pure
for a minimal definition. It's worth noting that we can get fmap
from those, though:
fmap f a = pure f <*> a
Similarly we can get the applicative definition from monads:
pure = return
f' <*> a' = do
f <- f'
a <- a'
return $ f a
You could look at applicatives functors a generalization of functors to multi argument functions or as combining values with context horizontally:
liftA2 f a b = f <$> a <*> b
fmap :: (a -> b) -> (f a -> f b)
liftA2 :: (a -> b -> c) -> (f a -> f b -> f c)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With