モナスは、理論的には、それがHaskellの型システムには示されていないにもかかわらず、理論的にはファンクタのサブセットであり、具体的には適用可能なファンクタであることが知られている。どのように、モナド与えられた、ことを知り、return
とbind
に基づかモナドがファンクタと応用ファンクタであることを示すには?
:
fmap
を導出
- は
<*>
を導き出しますか?
モナスは、理論的には、それがHaskellの型システムには示されていないにもかかわらず、理論的にはファンクタのサブセットであり、具体的には適用可能なファンクタであることが知られている。どのように、モナド与えられた、ことを知り、return
とbind
に基づかモナドがファンクタと応用ファンクタであることを示すには?
:
fmap
を導出
<*>
を導き出しますか?まあ、はちょうど(a -> b) -> f a -> f b
です。つまり、モナディックアクションの結果を純粋な関数で変換したいと考えています。これはControl.Monad.liftM
として利用可能である
fmap f m = m >>= \a -> return (f a)
:
fmap f m = do
a <- m
return (f a)
または、 "生" 書かれた:それはやる記法で書くのは簡単です。
pure :: a -> f a
はもちろんreturn
です。 (<*>) :: f (a -> b) -> f a -> f b
はややトリッキーです。関数を返すアクションとその引数を返すアクションがあり、その結果を返すアクションが必要です。で再び表記の操作を行います。
mf <*> mx = do
f <- mf
x <- mx
return (f x)
または、脱糖:
mf <*> mx =
mf >>= \f ->
mx >>= \x ->
return (f x)
多田!これはControl.Monad.ap
として利用可能であるので、次のように我々はすべてのモナドM
ためFunctor
とApplicative
の完全なインスタンスを与えることができます:理想的
instance Functor M where
fmap = liftM
instance Applicative M where
pure = return
(<*>) = ap
を、私たちは、負担を軽減するために、Monad
に直接これらの実装を指定することができるだろうthis proposalなど、すべてのモナドに個別のインスタンスを定義することができます。その場合、Applicative
のスーパークラスをMonad
というスーパークラスにすることには実質的な障害はありません。既存のコードを破らないようにするためです。一方、これは、与えられたMonad
のFunctor
とApplicative
のインスタンスを定義するのに必要な定型文は最小限であるため、「良い市民」(そしてそのようなインスタンスはどのモナドに対しても定義する必要があります)になりやすいことを意味します。
与えられた 'Monad'インスタンス' m'が実際にMonadの法則を満たしているとすれば、あなたが 'fmap'、' pure'と '(<*>)'に提供するモナドの定義は、 FunctorおよびApplicativeの法律に従います。 Haskellが強制するのは、型チェックだけです。 –