อะไรคือความสัมพันธ์ระหว่าง Alternative, MonadPlus (LeftCatch) และ MonadPlus (LeftDistributive)?


12

การติดตามตัวอย่างของ Monad ซึ่งเป็นทางเลือก แต่ไม่ใช่ MonadPlus คืออะไร :

สมมติว่าเป็น monad อะไรคือความสัมพันธ์ betweem เมตรเป็นทางเลือกที่MonadPlusCatchและMonadPlusDistr ? mmสำหรับแต่ละคู่ที่เป็นไปได้ทั้งหกคู่นั้นฉันต้องการพิสูจน์ว่ามีนัยหนึ่งหรืออีกตัวอย่างหนึ่งที่ไม่เป็นเช่นนั้น

(ฉันกำลังใช้

  • MonadPlusCatchเพื่อแยกความแตกต่างของMonadPlusที่เป็นไปตามกฎLeft-Catch :

    mplus (return a) b = return a
    
  • MonadPlusDistrเพื่อแยกความแตกต่างของMonadPlusที่ทำให้กฎการกระจายซ้าย :

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

ดูMonadPlus บน HaskellWiki )


ความรู้และสัญชาตญาณปัจจุบันของฉันคือ:

  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มันพิสูจน์ได้เพราะเราสามารถวิเคราะห์ได้ว่าaเป็นJust somethingหรือNothing- ดูคำตอบของ AndrewC ข้างต้น)

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

คำตอบ:


8

(เพราะอย่างที่ Petr Pudlákชี้ให้เห็น[]เป็นตัวอย่าง - มันไม่ตอบสนองMonadPlusCatchแต่ไม่พอใจMonadPlusDistดังนั้นจึงใช้งานได้ )

สันนิษฐานว่า: MonadPlus กฎหมายหมอก

-- (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

<*>การขยายตัวแทรก
สมมติเราใช้รากศัพท์มาตรฐานของ applicative จาก 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)

<$>การขยายตัวแทรก
สมมติเราใช้รากศัพท์มาตรฐาน functor จาก 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 อย่างน้อยก็เป็น monoid

Dist ขวา <*>

ฉันจะพิสูจน์

(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 >>=

ตามความจำเป็น.

Dist ซ้าย <$>

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 <$>ไม่กระทำการใด ๆ ที่เป็นสำนวนมันบริสุทธิ์ดังนั้นจึงอาจเป็นไปได้ที่จะ "สลับข้าง"
Petr Pudlák

@ PetrPudlák Updated - []หลักฐานเสร็จสิ้นแล้วและเพิ่มขึ้นประมาณ
AndrewC

@ PetrPudlákคุณคิดว่าเราควรเพิ่มหลักฐานที่[]สอดคล้องกับMonadPlusCatch หรือไม่? ในขณะนี้เป็นเพียงการยืนยันใน HaskellWiki >>= kมีการกำหนดไว้อย่างชัดเจนโดยใช้foldr ((++).k)
AndrewC

ฉันคิดว่าคุณหมายถึงMonadPlusDistใช่ไหม ฉันคิดว่าเราทำได้นี่จะพิสูจน์การพิสูจน์ได้อย่างสมบูรณ์
Petr Pudlák

@ 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 EitherApplicative


เหตุผลก็คือ

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

ละเว้นg(เนื่องจากLeftCatch ) และประเมินผลเพียง

return x `ap` a

แต่สิ่งนี้แตกต่างจากสิ่งที่อีกฝ่ายประเมิน:

g `ap` a
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.