Alternative,MonadPlus(LeftCatch)和MonadPlus(LeftDistributive)之间有什么关系?


12

跟进什么是替代而不是MonadPlus的Monad示例?

假设是单子。什么是关系betweem 是一个另类,一个MonadPlusCatchMonadPlusDistrmm对于六种可能的组合中的每一种,我都希望有一个证据表明一个隐含着另一个,或者有一个反例却没有。

(我在用着

  • MonadPlusCatch用来区分满足Left-Catch规则的MonadPlus

    mplus (return a) b = return a
    
  • MonadPlusDistr区分MonadPlus是satifies 左分配规则:

    mplus a b >>= k = mplus (a >>= k) (b >>= k)
    

请参阅HaskellWiki上的MonadPlus。)


我目前的知识和直觉是:

  1. MonadPlusDist 替代 - 可能是正确的 - 似乎很简单,我相信我有一个证明的草图,我将对其进行检查,如果它是正确的,我会将其张贴在 AndrewC回答的这一部分。
  2. Maybe
  3. MaybeT (Either e)MaybeT m'

    ((pure x) <|> g) <*> a =    -- LeftCatch
        (pure x) <*> a
    -- which in general cannot be equal to
    ((pure x) <*> a) <|> (g <*> a)
    

    再次,我将检查并发布。(有趣的是,仅仅Maybe是证明的,因为我们可以分析,如果aJust somethingNothing-见上述AndrewC的回答)

  4. [][]
  5. []
  6. Maybe

Answers:


8

(因为正如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的应用程序的标准派生,即(<*>) = appure = 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 >>=

按要求


1
大。我什至怀疑任何应用程序的右定律都暗含了左定律,但到目前为止我还没有证据。直觉是,f <$>它没有任何惯用行为,它是纯净的,因此有可能以某种方式“扭转局面”。
PetrPudlák'12 -10-31

@PetrPudlák已更新完成的证明,并增加了有关的推论[]
AndrewC

@PetrPudlák您认为我们应该添加[]满足MonadPlusCatch的证明吗?目前,这只是HaskellWiki上的一个断言。>>= k使用foldr ((++).k)
AndrewC

我想你是说MonadPlusDist,不是吗?我认为我们可以,这将完成推论的证明。
彼得·普德拉克(PetrPudlák),2012年

@PetrPudlák哦,对不起。会做。
AndrewC

6

确实是MaybeT Either

{-# LANGUAGE FlexibleInstances #-}
import Control.Applicative
import Control.Monad
import Control.Monad.Trans.Maybe

instance (Show a, Show b) => Show (MaybeT (Either b) a) where
    showsPrec _ (MaybeT x) = shows x

main = print $
    let
        x = id :: Int -> Int
        g = MaybeT (Left "something")
        a = MaybeT (Right Nothing)
    -- print the left/right side of the left distribution law of Applicative:
    in ( ((return x) `mplus` g) `ap` a
       , ((return x) `ap` a) `mplus` (g `ap` a)
       )

输出是

(Right Nothing, Left "something")

这意味着MaybeT Either不符合的左分布规律Applicative


原因是

(return x `mplus` g) `ap` a

忽略g(由于LeftCatch)并仅求

return x `ap` a

但这与另一方评估的结果不同:

g `ap` a
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.