モナドは、Haskell の型システムでは示されていませんが、理論的にはファンクターのサブセットであり、具体的には適用可能なファンクターであることが知られています。
モナドが与えられ、 と に基づいていることを知っているreturnとbind、次のようになります。
- 導出
fmap、 - 派生
<*>?
モナドは、Haskell の型システムでは示されていませんが、理論的にはファンクターのサブセットであり、具体的には適用可能なファンクターであることが知られています。
モナドが与えられ、 と に基づいていることを知っているreturnとbind、次のようになります。
fmap、<*>?つまり、モナドアクションの結果を純粋な関数で変換したいのですfmap。(a -> b) -> f a -> f bこれは do 記法で簡単に書けます:
fmap f m = do
a <- m
return (f a)
または、「生」と書かれています:
fmap f m = m >>= \a -> return (f a)
これは として入手できますControl.Monad.liftM。
pure :: a -> f aもちろんreturnです。(<*>) :: f (a -> b) -> f a -> f b少しトリッキーです。関数を返すアクションとその引数を返すアクションがあり、その結果を返すアクションが必要です。再び do 記法で:
mf <*> mx = do
f <- mf
x <- mx
return (f x)
または、脱糖:
mf <*> mx =
mf >>= \f ->
mx >>= \x ->
return (f x)
多田!これは として利用できるので、次のように任意のモナドに対してとControl.Monad.apの完全なインスタンスを与えることができます:FunctorApplicativeM
instance Functor M where
fmap = liftM
instance Applicative M where
pure = return
(<*>) = ap
理想的には、この提案Monadのように、モナドごとに個別のインスタンスを定義する負担を軽減するために、これらの実装を で直接指定できます。そうなった場合、のスーパークラスを作成するのに実質的な障害はありません。既存のコードを壊さないことが保証されるからです。一方、これは、特定のインスタンスの定義に関与するボイラープレートが最小限であることを意味するため、「善良な市民」になるのは簡単です (そして、そのようなインスタンスはモナドに対して定義する必要があります)。ApplicativeMonadFunctorApplicativeMonad