我无法理解维基百科对"应用函子"的定义

mml*_*lab 12 monads haskell functor applicative

在Haskell学习函子,应用函子和monad,我在维基百科上找到了这个定义:

在函数编程,具体Haskell中,一个适用函子是像一个的结构单子(return,fmap,join),而不join,或类似的一个函子return.

我无法理解:在我看来,提供return(即pure)一个仿函数不足以获得一个应用仿函数,因为你也需要提供ap(即<*>),这不能用fmapreturn仅用来定义.我错过了什么或维基百科的定义不完全正确吗?

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

Zet*_*eta 9

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

pure :: Monad m => a -> m a
pure = return
Run Code Online (Sandbox Code Playgroud)

我们不能,然而,定义(<*>)fmapreturn唯一的.我们所拥有的只是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'
Run Code Online (Sandbox Code Playgroud)

一个应用程序仿函数就像一个带有returnap但没有的仿函数join.所以,是的,你是完全正确的,维基百科错过了申请的运作(见原始论文).

顺便说一句,如果你只添加pure,你会得到一个尖头的仿函数.但是,类词列表提供了比维基Applicative百科文章更好的概述.

  • 请注意,我使用"不正确".我礼貌地修复了这篇文章. (2认同)

Tar*_*ren 7

你是正确的,适用的仿函数需要<*>以及pure最小的定义.值得注意的是,我们可以从中获取fmap,但是:

fmap f a = pure f <*> a
Run Code Online (Sandbox Code Playgroud)

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

pure = return
f' <*> a' = do
    f <- f'
    a <- a'
    return $ f a
Run Code Online (Sandbox Code Playgroud)

您可以查看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)
Run Code Online (Sandbox Code Playgroud)