mml*_*lab 12 monads haskell functor applicative
在Haskell学习函子,应用函子和monad,我在维基百科上找到了这个定义:
在函数编程,具体Haskell中,一个适用函子是像一个的结构单子(
return
,fmap
,join
),而不join
,或类似的一个函子带return
.
我无法理解:在我看来,提供return
(即pure
)一个仿函数不足以获得一个应用仿函数,因为你也需要提供ap
(即<*>
),这不能用fmap
和return
仅用来定义.我错过了什么或维基百科的定义不完全正确吗?
编辑2017-02-08:我在这个答案中找到了关于这个问题的其他有用的见解.
这篇文章不正确.假设我们有一个m
没有的monad join
,或者有一个functor return
.我们可以pure
立即定义:
pure :: Monad m => a -> m a
pure = return
Run Code Online (Sandbox Code Playgroud)
我们不能,然而,定义(<*>)
与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'
Run Code Online (Sandbox Code Playgroud)
一个应用程序仿函数就像一个带有return
和ap
但没有的仿函数join
.所以,是的,你是完全正确的,维基百科错过了申请的运作(见原始论文).
顺便说一句,如果你只添加pure
,你会得到一个尖头的仿函数.但是,类词列表提供了比维基Applicative
百科文章更好的概述.
你是正确的,适用的仿函数需要<*>
以及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)