![](/img/trans.png)
[英]How can I show that `Monad` is actually `Applicative` and `Functor`?
[英]How to show that a monad is a functor and an applicative functor?
Monad在理論上被認為是仿函數的一個子集,特別是應用仿函數,盡管它沒有在Haskell的類型系統中指出。
知道這一點,給定一個monad並基於return
和bind
,如何:
fmap
, <*>
? 好吧, fmap
只是(a -> b) -> fa -> fb
,即我們想用純函數轉換monadic動作的結果。 用符號寫起來很容易:
fmap f m = do
a <- m
return (f a)
或者,寫成“原始”:
fmap f m = m >>= \a -> return (f a)
這可以作為Control.Monad.liftM
。
pure :: a -> fa
當然是return
。 (<*>) :: f (a -> b) -> fa -> fb
有點棘手。 我們有一個返回一個函數的動作,一個返回其參數的動作,我們想要一個動作返回它的結果。 再做一次記錄:
mf <*> mx = do
f <- mf
x <- mx
return (f x)
或者,desugared:
mf <*> mx =
mf >>= \f ->
mx >>= \x ->
return (f x)
田田! 這可以作為Control.Monad.ap
,因此我們可以為任何monad M
提供Functor
和Applicative
的完整實例,如下所示:
instance Functor M where
fmap = liftM
instance Applicative M where
pure = return
(<*>) = ap
理想情況下,我們可以直接在Monad
指定這些實現,以減輕為每個monad定義單獨實例的負擔,例如使用此提議 。 如果發生這種情況,那么使Applicative
成為Monad
的超類將沒有真正的障礙,因為它將確保它不會破壞任何現有代碼。 另一方面,這意味着為給定Monad
定義Functor
和Applicative
實例所涉及的樣板文件很少,因此很容易成為“好公民”(並且應該為任何monad定義此類實例)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.