Mối quan hệ giữa Alternative, MonadPlus (LeftCatch) và MonadPlus (LeftDistributive) là gì?


12

Theo dõi Ví dụ về Monad là gì thay thế nhưng không phải là MonadPlus? :

Giả sử là một đơn nguyên. Các mối quan hệ betweem là một Thay thế , MonadPlusCatchMonadPlusDistr là gì? mmĐối với mỗi sáu cặp có thể, tôi muốn có một bằng chứng cho thấy một cặp ngụ ý khác hoặc một ví dụ ngược lại rằng nó không có.

(Tôi đang sử dụng

  • MonadPlusCatch để phân biệt MonadPlus đáp ứng quy tắc Bắt trái :

    mplus (return a) b = return a
    
  • MonadPlusDistr để phân biệt MonadPlus làm bão hòa quy tắc Phân phối trái :

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

xem MonadPlus trên HaskellWiki .)


Kiến thức hiện tại + trực giác của tôi là:

  1. MonadPlusDist Alternative - có thể đúng - có vẻ đơn giản, tôi tin rằng tôi đã phác thảo bằng chứng, tôi sẽ kiểm tra và nếu đúng, tôi sẽ đăng nó AndrewC đã trả lời phần này.
  2. Thay thế MonadPlusDist - sai - như AndrewC đã thể hiện trong câu trả lời của mình : là một Thay thế , nhưng được biết đó không phải là MonadPlusDist (đó là MonadPlusCatch ). Maybe
  3. MonadPlusCatch Alternative - có thể sai - Tôi tin rằng (hoặc về cơ bản là bất cứ thứ gì ) sẽ đóng vai trò là một ví dụ mẫu. Lý do là 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)
    

    một lần nữa tôi sẽ kiểm tra và đăng bài. (Điều thú vị là chỉ Maybenó chứng minh, bởi vì chúng ta có thể phân tích nếu aJust somethinghay Nothing-. Xem câu trả lời nói trên AndrewC của)

  4. Thay thế MonadPlusCatch - có thể sai - nếu chúng tôi chứng minh rằng MonadPlusDist Alternative thì sẽ phục vụ như một ví dụ ngược lại. (Hoặc chúng tôi có thể chứng minh rõ ràng các luật thay thế cho .) [][]
  5. MonadPlusDist MonadPlusCatch - sai - là một ví dụ phản biện đã biết. []
  6. MonadPlusCatch MonadPlusDist - sai - là một ví dụ phản biện đã biết. Maybe

Câu trả lời:


8

(vì như Petr Pudlák đã chỉ ra, []là một ví dụ - nó không thỏa mãn MonadPlusCatch nhưng lại làm hài lòng MonadPlusDist , do đó có thể áp dụng )

Giả sử: Luật MonadPlusDist

-- (mplus,mzero) is a monoid
mzero >>= k = mzero`                             -- left identity >>=
(a `mplus` b) >>= k  =  (a >>=k) `mplus` (b>>=k) -- left dist mplus

Để chứng minh: Luật thay thế

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

<*>bổ đề mở rộng
Giả sử chúng ta sử dụng đạo hàm chuẩn của một ứng dụng từ một đơn nguyên, cụ thể là (<*>) = appure = return. Sau đó

mf <*> mx = mf >>= \f -> mx >>= \x -> return (f x)

bởi vì

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)

<$>bổ đề mở rộng
Giả sử chúng ta sử dụng đạo hàm chuẩn của một functor từ một đơn nguyên, cụ thể là (<$>) = liftM. Sau đó

f <$> mx = mx >>= return . f

bởi vì

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 

Bằng chứng

Giả sử ( <+>, m0) thỏa mãn luật MonadPlus. Sau đó, nó là một monoid.

Đúng quận <*>

Tôi sẽ chứng minh

(mf <+> mg) <*> ma = (mf <*> ma) <+> (mg <*> ma) -- right dist <*>

bởi vì nó dễ dàng hơn trên ký hiệu.

(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

Danh tính trái <*>

mzero <*> mx = mzero >>= \f -> mx >>= \x -> return (f x) -- <*> expansion
             = mzero                                     -- left identity >>=

theo yêu cầu.

Còn lại quận <$>

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

theo yêu cầu


1
Tuyệt quá. Tôi thậm chí nghi ngờ rằng các luật trái được ngụ ý bởi các luật phải cho bất kỳ Đơn đăng ký nào , nhưng cho đến nay tôi không có bằng chứng nào. Trực giác là f <$>không thực hiện bất kỳ hành động thành ngữ nào, đó là thuần túy, do đó có thể bằng cách nào đó "chuyển đổi các bên".
Petr Pudlák

@ PetrPudlák Cập nhật - hoàn thành bằng chứng và thêm hệ quả của bạn về [].
AndrewC

@ PetrPudlák Bạn có nghĩ rằng chúng ta nên thêm một bằng chứng []thỏa mãn MonadPlusCatch không? Hiện tại, đó chỉ là một khẳng định trên HaskellWiki. >>= kđược định nghĩa rõ ràng bằng cách sử dụngfoldr ((++).k)
AndrewC

Tôi cho rằng bạn có nghĩa là MonadPlusDist , phải không? Tôi nghĩ rằng chúng ta có thể, điều này sẽ hoàn thành bằng chứng của hệ quả.
Petr Pudlák

@ PetrPudlák Ồ vâng tôi xin lỗi. Sẽ làm.
AndrewC

6

Thật vậy, đó là 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)
       )

Đầu ra là

(Right Nothing, Left "something")

có nghĩa là MaybeT Eitherthất bại trong luật phân phối trái của Applicative.


Lý do là

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

bỏ qua g(do LeftCatch ) và đánh giá chỉ để

return x `ap` a

nhưng điều này khác với những gì phía bên kia đánh giá:

g `ap` a
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.