我无法理解维基百科对 "applicative functor" 的定义
I can't understand Wikipedia's definition of "applicative functor"
研究 Haskell 中的函子、应用函子和单子,我在 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
.
我无法理解:在我看来,向函子提供return
(即pure
)不足以获得应用函子,因为您需要提供ap
(即 <*>
),不能仅根据 fmap
和 return
来定义。是我遗漏了什么还是维基百科的定义不完全正确?
编辑 2017-02-08:我在 答案中找到了关于这个问题的其他有用见解。
你是对的,应用仿函数需要 <*>
和 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)
这篇文章不正确。假设我们有一个没有 join
的单子 m
,或者一个有 return
的仿函数。我们可以立即定义pure
:
pure :: Monad m => a -> m a
pure = return
但是,我们不能只用 fmap
和 return
来定义 (<*>)
。我们只有 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'
应用函子就像一个有 return
和 ap
但没有 join
的函子。所以是的,你是完全正确的,维基百科错过了 applicative 的操作(参见 the original paper)。
顺便说一下,如果您只添加 pure
,您会得到一个 pointed functor. The typeclassopedia 提供比维基百科文章更好的 Applicative
概述。
研究 Haskell 中的函子、应用函子和单子,我在 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
.
我无法理解:在我看来,向函子提供return
(即pure
)不足以获得应用函子,因为您需要提供ap
(即 <*>
),不能仅根据 fmap
和 return
来定义。是我遗漏了什么还是维基百科的定义不完全正确?
编辑 2017-02-08:我在
你是对的,应用仿函数需要 <*>
和 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)
这篇文章不正确。假设我们有一个没有 join
的单子 m
,或者一个有 return
的仿函数。我们可以立即定义pure
:
pure :: Monad m => a -> m a
pure = return
但是,我们不能只用 fmap
和 return
来定义 (<*>)
。我们只有 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'
应用函子就像一个有 return
和 ap
但没有 join
的函子。所以是的,你是完全正确的,维基百科错过了 applicative 的操作(参见 the original paper)。
顺便说一下,如果您只添加 pure
,您会得到一个 pointed functor. The typeclassopedia 提供比维基百科文章更好的 Applicative
概述。