简体   繁体   English

如何证明monad是一个仿函数和一个应用函子?

[英]How to show that a monad is a functor and an applicative functor?

Monads are known to be theoretically a subset of functors and specifically applicative functors, even though it's not indicated in Haskell's type system. Monad在理论上被认为是仿函数的一个子集,特别是应用仿函数,尽管它没有在Haskell的类型系统中指出。

Knowing that, given a monad and basing on return and bind , how to: 知道这一点,给定一个monad并基于returnbind ,如何:

  • derive fmap , 派生fmap
  • derive <*> ? 派生<*>

Well, fmap is just (a -> b) -> fa -> fb , ie we want to transform the monadic action's result with a pure function. 好吧, fmap只是(a -> b) -> fa -> fb ,即我们想用纯函数转换monadic动作的结果。 That's easy to write with do notation: 用符号写起来很容易:

fmap f m = do
  a <- m
  return (f a)

or, written "raw": 或者,写成“原始”:

fmap f m = m >>= \a -> return (f a)

This is available as Control.Monad.liftM . 这可以作为Control.Monad.liftM

pure :: a -> fa is of course return . pure :: a -> fa当然是return (<*>) :: f (a -> b) -> fa -> fb is a little trickier. (<*>) :: f (a -> b) -> fa -> fb有点棘手。 We have an action returning a function, and an action returning its argument, and we want an action returning its result. 我们有一个返回一个函数的动作,一个返回其参数的动作,我们想要一个动作返回它的结果。 In do notation again: 再做一次记录:

mf <*> mx = do
  f <- mf
  x <- mx
  return (f x)

Or, desugared: 或者,desugared:

mf <*> mx =
  mf >>= \f ->
  mx >>= \x ->
  return (f x)

Tada! 田田! This is available as Control.Monad.ap , so we can give a complete instance of Functor and Applicative for any monad M as follows: 这可以作为Control.Monad.ap ,因此我们可以为任何monad M提供FunctorApplicative的完整实例,如下所示:

instance Functor M where
  fmap = liftM

instance Applicative M where
  pure = return
  (<*>) = ap

Ideally, we'd be able to specify these implementations directly in Monad , to relieve the burden of defining separate instances for every monad, such as with this proposal . 理想情况下,我们可以直接在Monad指定这些实现,以减轻为每个monad定义单独实例的负担,例如使用此提议 If that happens, there'll be no real obstacle to making Applicative a superclass of Monad , as it'll ensure it doesn't break any existing code. 如果发生这种情况,那么使Applicative成为Monad的超类将没有真正的障碍,因为它将确保它不会破坏任何现有代码。 On the other hand, this means that the boilerplate involved in defining Functor and Applicative instances for a given Monad is minimal, so it's easy to be a "good citizen" (and such instances should be defined for any monad). 另一方面,这意味着为给定Monad定义FunctorApplicative实例所涉及的样板文件很少,因此很容易成为“好公民”(并且应该为任何monad定义此类实例)。

fmap = liftM and (<*>) = ap . fmap = liftM(<*>) = ap Here are links to the source code for liftM and ap . 以下是liftMap源代码的链接。 I presume you know how to desugar do notation. 我认为你知道如何desugar做符号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM