什么是单子这是一个另类,但不是MonadPlus的例子吗?(What’s an example of

2019-07-03 10:18发布

在他的回答这个问题“类型类之间的区别MonadPlusAlternativeMonoid ?” ,爱德华Kmett说,

此外,即使Applicative是一个超Monad ,你拉闸需要的MonadPlus类反正,因为服从

 empty <*> m = empty 

不严格不足以证明

 empty >>= f = empty 

所以声称的东西是MonadPlus比声称这是更强的Alternative

很明显,任何适用函子这不是一个单子是自动的示例Alternative它不是MonadPlus ,但爱德华Kmett的回答意味着存在一个单子这是一个Alternative ,但不是MonadPlus :其empty<|>会满足Alternative法律,1而不是MonadPlus法律。 2,我不能拿出我自己的这个例子; 有谁知道一个吗?


1我没能找到一组标准基准Alternative法律,但我给出了什么,我相信他们能够通过大致一半是我的回答这个问题通过的意义困惑” Alternative型类及其关系其他类型的类” (搜索短语‘右分配律’)。 四条律,我相信应该是持有:

  1. 右分配性(的<*> (f <|> g) <*> a = (f <*> a) <|> (g <*> a)
  2. 右吸收(对于<*> empty <*> a = empty
  3. 左分配性(的fmap ): f <$> (a <|> b) = (f <$> a) <|> (f <$> b)
  4. 左吸收(对于fmap ): f <$> empty = empty

我也高兴地接受被赋予更有用的一套Alternative法律。

2我知道有关于什么有些含糊不清MonadPlus法律 ; 我很高兴与使用左侧分配或左抓一个答案,但我会弱倾向于前者。

Answer 1:

该线索,你的答案是在约MonadPlus HaskellWiki您链接到 :

哪些规则? 马丁·吉本斯选择含半幺群,左零,和左侧分布。 这使得[]一个MonadPlus,但不是MaybeIO

所以要根据你喜欢的选择, Maybe不是MonadPlus(虽然有一个实例,它不满足左侧分配)。 让我们证明它满足替代。

Maybe是一种替代

  1. 右分配性(的<*> (f <|> g) <*> a = (f <*> a) <|> (g <*> a)

案例1: f=Nothing

(Nothing <|> g) <*> a =                    (g) <*> a  -- left identity <|>
                      = Nothing         <|> (g <*> a) -- left identity <|>
                      = (Nothing <*> a) <|> (g <*> a) -- left failure <*>

案例2: a=Nothing

(f <|> g) <*> Nothing = Nothing                             -- right failure <*>
                      = Nothing <|> Nothing                 -- left identity <|>
                      = (f <*> Nothing) <|> (g <*> Nothing) -- right failure <*>

案例3: f=Just h, a = Just x

(Just h <|> g) <*> Just x = Just h <*> Just x                      -- left bias <|>
                          = Just (h x)                             -- success <*>
                          = Just (h x) <|> (g <*> Just x)          -- left bias <|>
                          = (Just h <*> Just x) <|> (g <*> Just x) -- success <*>
  1. 右吸收(对于<*> empty <*> a = empty

这很简单,因为

Nothing <*> a = Nothing    -- left failure <*>
  1. 左分配性(的fmap ): f <$> (a <|> b) = (f <$> a) <|> (f <$> b)

案例1: a = Nothing

f <$> (Nothing <|> b) = f <$> b                        -- left identity <|>
                 = Nothing <|> (f <$> b)          -- left identity <|>
                 = (f <$> Nothing) <|> (f <$> b)  -- failure <$>

案例2: a = Just x

f <$> (Just x <|> b) = f <$> Just x                 -- left bias <|>
                     = Just (f x)                   -- success <$>
                     = Just (f x) <|> (f <$> b)     -- left bias <|>
                     = (f <$> Just x) <|> (f <$> b) -- success <$>
  1. 左吸收(对于fmap ): f <$> empty = empty

另一个简单的一个:

f <$> Nothing = Nothing   -- failure <$>

Maybe不是MonadPlus

让我们来证明这一说法Maybe不是MonadPlus:我们需要证明mplus ab >>= k = mplus (a >>= k) (b >>= k)并不总是持有。 诀窍是,以往一样,使用一些有约束力的潜行非常不同的值了:

a = Just False
b = Just True

k True = Just "Made it!"
k False = Nothing

现在

mplus (Just False) (Just True) >>= k = Just False >>= k
                                     = k False
                                     = Nothing

这里我用绑定(>>=)以抓举失败( Nothing从胜利的下巴),因为Just False看起来像成功。

mplus (Just False >>= k) (Just True >>= k) = mplus (k False) (k True)
                                           = mplus Nothing (Just "Made it!")
                                           = Just "Made it!"

在这里,出现故障( k False )被提前计算,所以他被忽视,我们"Made it!"

所以, mplus ab >>= k = Nothing ,但mplus (a >>= k) (b >>= k) = Just "Made it!"

你可以看一下这是我使用>>=打破左偏mplusMaybe

我的证据的合法性:

万一你觉得我做的还不够繁琐的推导,我会证明我以前的身份:

首先

Nothing <|> c = c      -- left identity <|>
Just d <|> c = Just d  -- left bias <|>

其中来自实例声明

instance Alternative Maybe where
    empty = Nothing
    Nothing <|> r = r
    l       <|> _ = l

其次

f <$> Nothing = Nothing    -- failure <$>
f <$> Just x = Just (f x)  -- success <$>

其中刚刚从(<$>) = fmap

instance  Functor Maybe  where
    fmap _ Nothing       = Nothing
    fmap f (Just a)      = Just (f a)

第三,其他三个需要更多的工作:

Nothing <*> c = Nothing        -- left failure <*>
c <*> Nothing = Nothing        -- right failure <*>
Just f <*> Just x = Just (f x) -- success <*>

它来自定义

instance Applicative Maybe where
    pure = return
    (<*>) = ap

ap :: (Monad m) => m (a -> b) -> m a -> m b
ap =  liftM2 id

liftM2  :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 f m1 m2          = do { x1 <- m1; x2 <- m2; return (f x1 x2) }

instance  Monad Maybe  where
    (Just x) >>= k      = k x
    Nothing  >>= _      = Nothing
    return              = Just

所以

mf <*> mx = ap mf mx
          = liftM2 id mf mx
          = do { f <- mf; x <- mx; return (id f x) }
          = do { f <- mf; x <- mx; return (f x) }
          = do { f <- mf; x <- mx; Just (f x) }
          = mf >>= \f ->
            mx >>= \x ->
            Just (f x)

因此,如果mfmx是没有什么,结果是也Nothing ,而如果mf = Just fmx = Just x ,结果是Just (fx)



文章来源: What’s an example of a Monad which is an Alternative but not a MonadPlus?