→
→
(因为正如PetrPudlák所指出的,这[]
是一个反例-它不满足MonadPlusCatch但确实满足MonadPlusDist,因此为Applicative)
假设:MonadPlusDist法律
-- (mplus,mzero) is a monoid
mzero >>= k = mzero` -- left identity >>=
(a `mplus` b) >>= k = (a >>=k) `mplus` (b>>=k) -- left dist mplus
证明:替代法
-- ((<|>),empty) is a monoid
(f <|> g) <*> a = (f <*> a) <|> (g <*> a) -- right dist <*>
empty <*> a = empty -- left identity <*>
f <$> (a <|> b) = (f <$> a) <|> (f <$> b) -- left dist <$>
f <$> empty = empty -- empty fmap
<*>
扩展引理
假设我们使用一个monad的应用程序的标准派生,即(<*>) = ap
和pure = return
。然后
mf <*> mx = mf >>= \f -> mx >>= \x -> return (f x)
因为
mf <*> mx = ap mf mx -- premise
= liftM2 id mf mx -- def(ap)
= do { f <- mf; x <- mx; return (id f x) } -- def(liftM2)
= mf >>= \f -> mx >>= \x -> return (id f x) -- desugaring
= mf >>= \f -> mx >>= \x -> return (f x) -- def(id)
<$>
扩展引理
假设我们使用从monad的函子的标准派生,即(<$>) = liftM
。然后
f <$> mx = mx >>= return . f
因为
f <$> mx = liftM f mx -- premise
= do { x <- mx; return (f x) } -- def(liftM)
= mx >>= \x -> return (f x) -- desugaring
= mx >>= \x -> (return.f) x -- def((.))
= mx >>= return.f -- eta-reduction
证明
假设(<+>
,m0
)满足MonadPlus法则。琐碎的是一个类人动物。
右区 <*>
我会证明
(mf <+> mg) <*> ma = (mf <*> ma) <+> (mg <*> ma) -- right dist <*>
因为在符号上更容易。
(mf <+> mg) <*> ma = (mf <+> mg) >>= \forg -> mx >>= \x -> return (forg x) -- <*> expansion
= (mf >>= \f_g -> mx >>= \x -> return (f_g x))
<+> (mg >>= \f_g -> mx >>= \x -> return (f_g x)) -- left dist mplus
= (mf <*> mx) <+> (mg <*> mx) -- <*> expansion
左身份 <*>
mzero <*> mx = mzero >>= \f -> mx >>= \x -> return (f x) -- <*> expansion
= mzero -- left identity >>=
按要求。
左区 <$>
f <$> (a <|> b) = (f <$> a) <|> (f <$> b) -- left dist <$>
f <$> (a <+> b) = (a <+> b) >>= return . f -- <$> expansion
= (a >>= return.f) <+> (b >>= return.f) -- left dist mplus
= (f <$> a) <+> (f <$> b) -- <$> expansion
empty fmap
f <$> mzero = mzero >>= return.f -- <$> expansion
= mzero -- left identity >>=
按要求
f <$>
它没有任何惯用行为,它是纯净的,因此有可能以某种方式“扭转局面”。