当前位置: 首页 > 知识库问答 >
问题:

Monad是一个替代品,但不是MonadPlus的例子是什么?

宋典
2023-03-14

在他对问题“类型类MonadPlusAlternativeMonoid之间的区别”的回答中,Edward Kmett说

此外,即使ApplicativeMonad的一个超类,您最终还是需要MonadPlus类,因为遵守

empty <*> m = empty

严格来说还不足以证明这一点

empty >>= f = empty

因此,声称某样东西是一个MonadPlus比声称它是替代更强。

很明显,任何不是单子的应用函子都会自动成为替代的一个例子,它不是MonadPlus,但爱德华·科米特的回答暗示存在一个单子,它是替代,而不是单子:它的为空

1我找不到一套替代法的规范参考,但我在回答问题“被<代码>备选 类型类的含义及其与其他类型类的关系弄糊涂了”(搜索短语“正确的分配性”)的过程中,大致展示了我认为他们是什么。我认为应该遵守的四条法律是:

  1. 右分配性(of

我也很乐意接受一套更有用的替代法。

2我知道关于什么是MonadPlus法律有些模糊;我对使用左分布或左捕获的答案很满意,尽管我更喜欢前者。


共有1个答案

吕鹏
2023-03-14

关于MonadPlus的Haskell Wiki中有你答案的线索,你链接到:

什么规则?马丁

因此,根据您喜欢的选择,也许不是MonadPlus(尽管有一个实例,但它不满足左分布)。让我们证明它满足替代方案。

  1. 权利分配(的<代码>

案例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. 右吸收(用于

这很容易,因为

Nothing <*> a = Nothing    -- left failure <*>
  1. 左分布(offmap):f

案例1:a=无

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

另一个简单的问题是:

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

让我们来证明也许不是MonadPlus的断言:我们需要证明mplus a b

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

这里我使用了bind(

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

这里的失败(k False)是提前计算出来的,所以被忽略了,我们“成功了!”

所以,mplus a b

你可以用

以防你觉得我没有做足够繁琐的推导,我会证明我使用的身份:

首先

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

来自(

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都没有,结果也是没有,而如果mf=Just fmx=Just x,结果是Just(f x)

 类似资料:
  • 我试图理解背后的动机。如果已经存在类型类和,为什么有必要呢? 诚然,的实例是具体的类型,而的实例需要一个类型参数。(有关有用的解释,请参见Monoid vs MonadPlus。)但是你不能重写任何类型的约束吗 作为和的组合? 从。它的实施是: 我只能使用和实现它: 有人能澄清和之间的真正区别吗?

  • 问题内容: 我听说Liskov替代原理(LSP)是面向对象设计的基本原理。它是什么?有哪些使用示例? 问题答案: 一个很好的例子说明了LSP(我最近听到的一个播客中的Bob叔叔给了LSP),就是有时候听起来有些自然语言在代码中不太起作用。 在数学中,是。实际上,它是矩形的一种特殊形式。“是”使您想使用继承对其进行建模。但是,如果在您编写的代码中Square派生自Rectangle,则aSquare

  • 一个示例用例: 错误:无法取消应用scalaz的类型验证为类型为的类型构造函数,该类型构造函数由类型类 的实例造成的 我可以为自己做一个,比如: 但是为什么还没有呢?毕竟,已经定义了方法。 此外,我不能有和在一起了(这花了我很长时间才弄清楚...),因为另一个复杂的错误... 模糊的隐式值:类似于(我的实例)和trait中的方法...两者都匹配一些... 我应该修改scaraz的源代码吗?或者我完

  • 问题内容: 在教程中,我学会了使用。现在,我了解到,很多人对此表示反对。我已经尝试过,但随后它实际上将其发送到打印机。 那么我应该使用哪些替代方法,为什么不使用呢?w3schools和MDN都使用。 问题答案: 作为推荐的替代方法,您可以使用DOM操作直接查询节点元素并将其添加到DOM。

  • 对于此示例: 如何检查 是否是 Foo 的实例(但不是其 foo 子类的实例)?那是: checkInstance(qux,Foo.class)=true checkInstance(qux,Bar.class)=false 有没有类似于< code>instanceof的语句来进行这种检查?或者我应该使用< code>qux.getClass()。equals(Foo.class)

  • 本文向大家介绍lodash pluck()方法的替代品是什么?,包括了lodash pluck()方法的替代品是什么?的使用技巧和注意事项,需要的朋友参考一下 Pluck已从lodash 4中删除。这是因为它的作用与映射相同。 作为替换,您可以通过以下方式使用map函数- 示例 输出结果 这将给出输出-