I can't understand Wikipedia's definition of “applicative functor”

旧时模样 提交于 2019-12-06 19:05:09

问题


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) without join, or like a functor with return.

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.


回答1:


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.




回答2:


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)


来源:https://stackoverflow.com/questions/42043385/i-cant-understand-wikipedias-definition-of-applicative-functor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!