Quelles sont les relations entre Alternative, MonadPlus (LeftCatch) et MonadPlus (LeftDistributive)?


12

Suivi Quel est un exemple d'une Monade qui est une Alternative mais pas un MonadPlus? :

Supposons que est une monade. Quelles sont les relations betweem m étant une alternative , un MonadPlusCatch et un MonadPlusDistr ? mmPour chacune des six paires possibles, j'aimerais avoir soit une preuve que l'une en implique une autre, soit un contre-exemple que ce n'est pas le cas.

(J'utilise

  • MonadPlusCatch pour distinguer un MonadPlus qui satisfait à la règle de capture à gauche :

    mplus (return a) b = return a
    
  • MonadPlusDistr pour distinguer un MonadPlus qui satisfait la règle de distribution à gauche :

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

voir MonadPlus sur HaskellWiki .)


Mes connaissances et mon intuition actuelles sont les suivantes:

  1. MonadPlusDist Alternative - probablement vrai - cela semble simple, je crois que j'ai un croquis d'une preuve, je vais la vérifier et si elle est correcte, je la posterai AndrewC a répondu à cette partie.
  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)
    

    encore une fois, je vais vérifier et poster. (Fait intéressant, car Maybec'est tout simplement prouvable, car nous pouvons analyser si ac'est Just somethingou Nothing- voir la réponse d'AndrewC susmentionnée.)

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

Réponses:


8

(parce que, comme Petr Pudlák l'a souligné, []est un contre-exemple - il ne satisfait pas MonadPlusCatch mais satisfait MonadPlusDist , donc Applicative )

Supposé: MonadPlusDist Laws

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

Pour prouver: les lois alternatives

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

<*>lemme d'expansion
Supposons que nous utilisons la dérivation standard d'un applicatif à partir d'une monade, à savoir (<*>) = apet pure = return. alors

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

car

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)

<$>lemme d'expansion
Supposons que nous utilisons la dérivation standard d'un foncteur à partir d'une monade, à savoir (<$>) = liftM. alors

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

car

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 

Preuve

Supposons que ( <+>, m0) satisfasse aux lois MonadPlus. Trivial alors c'est un monoïde.

Dist droite <*>

Je vais prouver

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

car c'est plus facile sur la notation.

(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

Identité gauche <*>

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

comme demandé.

Dist gauche <$>

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

comme demandé


1
Génial. Je soupçonne même que les lois de gauche sont impliquées par les lois de droite pour tout candidat , mais je n'ai aucune preuve jusqu'à présent. L'intuition est que f <$>cela ne porte aucune action idiomatique, c'est pur, donc il pourrait être possible de "changer de camp".
Petr Pudlák

@ PetrPudlák Mise à jour - preuve terminée et ajout de votre corollaire [].
AndrewC

@ PetrPudlák Pensez-vous que nous devrions ajouter une preuve qui []satisfait MonadPlusCatch? Pour le moment, ce n'est qu'une affirmation sur le HaskellWiki. >>= kest défini explicitement en utilisantfoldr ((++).k)
AndrewC

Je suppose que tu veux dire MonadPlusDist , n'est-ce pas? Je pense que nous pourrions, cela compléterait la preuve du corollaire.
Petr Pudlák

@ PetrPudlák Oh oui, je suis désolé. Ça ira.
AndrewC

6

En effet c'est 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)
       )

La sortie est

(Right Nothing, Left "something")

ce qui signifie que MaybeT Eitherla loi de distribution de gauche de Applicative.


La raison en est que

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

ignore g(en raison de LeftCatch ) et évalue juste

return x `ap` a

mais cela est différent de ce que l'autre côté évalue:

g `ap` a
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.