我无法理解维基百科对" applicative functor"

时间:2017-02-04 17:34:31

标签: haskell monads functor applicative

在Haskell中研究仿函数,应用仿函数和monad,我在Wikipedia找到了这个定义:

  

在函数式编程中,特别是Haskell,一个 applicative   仿函数是一个类似 monad 的结构(returnfmapjoin)   没有join,或者像仿函数一样return

我无法理解:在我看来,向仿函数提供return(即pure)不足以获得一个应用仿函数,因为你需要提供{{1 } {(ap)也是,不能仅根据<*>fmap来定义。我错过了什么或者维基百科的定义不是绝对正确的吗?

编辑2017-02-08:我在this回答中找到了有关此问题的其他有用见解。

2 个答案:

答案 0 :(得分:9)

文章不正确。假设我们有一个没有m的monad join或一个return的仿函数。我们可以立即定义pure

pure :: Monad m => a -> m a
pure = return

但是,我们无法仅(<*>)fmap定义return。我们所拥有的只是fmap,因此如果我们尝试使用m (m a),我们最终会得到m (a -> b)。那时我们需要join或其等效的(>>=)

(<*>) :: 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'

应用仿函数就像一个returnap的仿函数,但没有join。所以,是的,你是完全正确的,维基百科错过了应用程序的运作(见the original paper)。

顺便说一句,如果您只添加pure,则会获得pointed functor。尽管如此,typeclassopedia提供了比{1}}更好的概述,而不是维基百科的文章。

答案 1 :(得分:7)

你是对的,应用函子需要<*>以及pure来获得最小的定义。值得注意的是,我们可以从这些中获得fmap

fmap f a = pure f <*> a

同样,我们可以从monads获得适用的定义:

pure = return
f' <*> a' = do
    f <- f'
    a <- a'
    return $ f a

您可以查看applicatives仿函数,将仿函数概括为多参数函数,或者将值与水平上下文相结合:

liftA2 f a b = f <$> a <*> b
fmap :: (a -> b) -> (f a -> f b)
liftA2 :: (a -> b -> c) -> (f a -> f b -> f c)