在 Haskell 中,Applicatives 被认为比 Functor 更强,这意味着我们可以使用 Applicative 来定义 Functor,例如
-- Functor
fmap :: (a -> b) -> f a -> f b
fmap f fa = pure f <*> fa
Monad 被认为比 Applicatives 和 Functor 更强,这意味着。
-- Functor
fmap :: (a -> b) -> f a -> f b
fmap f fa = fa >>= return . f
-- Applicative
pure :: a -> f a
pure = return
(<*>) :: f (a -> b) -> f a -> f b
(<*>) = ??? -- Can we define this in terms return & bind? without using "ap"
我读到 Monad 是用于对动作进行排序的。但我觉得 Monad 唯一能做的就是 Join 或 Flatten,它的其余功能来自 Applicatives。
join :: m (m a) -> m a
-- & where is the sequencing in this part? I don't get it.
如果 Monad 真的用于排序操作,那么我们如何定义 Applicatives(不被认为是严格按顺序操作,某种并行计算)?
由于单子是内函子类别中的幺半群。还有可交换幺半群,它们不一定需要按顺序工作。这意味着可交换幺半群的 Monad 实例也需要排序?
Edit:我发现了一个很棒的页面http://wiki.haskell.org/What_a_Monad_is_not http://wiki.haskell.org/What_a_Monad_is_not
如果 Monad 真的用于排序操作,那么我们如何定义 Applicatives(不被认为是严格按顺序操作,某种并行计算)?
不完全的。所有 monad 都是 applicative,但只有一些 applicative 是 monad。因此,给定一个 monad,您始终可以根据以下方式定义应用实例bind
and return
,但是如果您拥有的只是应用实例,那么您无法在没有更多信息的情况下定义 monad。
monad 的应用实例如下所示:
instance (Monad m) => Applicative m where
pure = return
f <*> v = do
f' <- f
v' <- v
return $ f' v'
当然这是评价f
and v
按顺序,因为它是一个 monad,而这就是 monad 所做的事情。如果这个应用不按顺序做事那么它就不是一个 monad。
当然,现代 Haskell 以相反的方式定义了这一点:Applicative
类型类是一个子集Functor
所以如果你有一个Functor
你可以定义(<*>)
那么你可以创建一个Applicative
实例。Monad
又被定义为Applicative
,所以如果你有一个Applicative
实例,你可以定义(>>=)
那么你可以创建一个Monad
实例。但你无法定义(>>=)
按照(<*>)
.
See the 类型分类百科全书 https://wiki.haskell.org/Typeclassopedia更多细节。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)