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



在Haskell中研究函子,应用函子和monads,我在维基百科上找到了这个定义:

在函数式编程中,特别是 Haskell,一种应用 函子是一个类似于monad的结构(returnfmapjoin( 没有join,或者像一个有return函子

我不明白:在我看来,提供return(即 pure(对函子的获得不足以获得应用函子,因为需要提供ap(即 <*> (也是如此,不能仅用fmapreturn来定义。我错过了什么还是维基百科的定义不是绝对正确的?

编辑2017-02-08:我在这个答案中找到了关于这个问题的其他有用见解。

这篇文章不正确。假设我们有一个没有join的 monad m,或者一个带有 return 的函子。我们可以立即定义pure

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

但是,我们不能仅用fmapreturn来定义(<*>)。我们所拥有的只是 fmap ,所以如果我们尝试使用m (a -> b),我们最终会得到m (m a)。此时我们需要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。所以是的,你是完全正确的,维基百科错过了应用的操作(见原始论文(。

顺便说一下,如果你只添加 pure ,你会得到一个尖头函子。不过,类型百科比维基百科文章提供了更好的Applicative概述。

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

fmap f a = pure f <*> a

类似地,我们可以从monads中得到应用定义:

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

您可以将应用函子视为多参数函数的泛化,或者将值与上下文水平组合:

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

最新更新