Haskell 什么&x2019;这是一个单子的例子,它是一个替代品,但不是单子?
在回答这个问题时,Edward Kmett说 此外,即使Haskell 什么&x2019;这是一个单子的例子,它是一个替代品,但不是单子?,haskell,monads,applicative,alternative-functor,monadplus,Haskell,Monads,Applicative,Alternative Functor,Monadplus,在回答这个问题时,Edward Kmett说 此外,即使Applicative是Monad的一个超类,您最终还是需要MonadPlus类,因为遵守 empty <*> m = empty 因此,声称某物是一个MonadPlus比声称它是替代品更有力 很明显,任何非单子的应用函子都会自动成为非单子的备选方案的示例,但是Edward Kmett的回答意味着存在一个单子,它是一个替代,而不是MonadPlus:它的为空和将满足替代法则,1但不是单子plus法则。2我自己无法想出一个这样的
Applicative
是Monad
的一个超类,您最终还是需要MonadPlus
类,因为遵守
empty <*> m = empty
因此,声称某物是一个MonadPlus
比声称它是替代品
更有力
很明显,任何非单子的应用函子都会自动成为非单子的备选方案的示例,但是Edward Kmett的回答意味着存在一个单子,它是一个替代
,而不是MonadPlus
:它的为空
和
将满足替代
法则,1但不是单子plus
法则。2我自己无法想出一个这样的例子;有人知道吗
1我无法找到一组替代
法则的规范参考,但我列出了我认为它们大概是问题的一半(搜索短语“正确分配”)。我认为应该遵守的四条法律是:
右分配性(of
):(f g)a=(f a)(g a)
右侧吸收(用于
):空a=empty
左分布(offmap
):f(ab)=(fa)(fb)
左吸收(用于fmap
):f empty=empty
我也很乐意接受一套更有用的替代法
2我知道这一点;我对使用左分布或左捕捉的答案很满意,尽管我不太喜欢前者。你答案的线索在:
什么规则?Martin和Gibbons选择幺半群、左零和左分布。这使得[]
成为一个MonadPlus,但不可能是或者IO
因此,根据您喜欢的选择,可能不是MonadPlus(虽然有一个实例,但它不满足左分布)。让我们证明它满足备选方案
可能是另一种选择
右分配性(of
):(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 <*>
(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 <*>
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 <$>
案例2:a=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 <*>
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 <$>
也许
不是MonadPlus
让我们来证明可能不是MonadPlus的断言:我们需要证明mplus a b>>=k=mplus(a>=k)(b>=k)
并不总是成立的。诀窍是,像以往一样,使用一些绑定来隐藏非常不同的值:
a = Just False
b = Just True
k True = Just "Made it!"
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>=k=Nothing
但是mplus(a>=k)(b>=k)=只是“成功了!”
您可以像我一样使用>=
来打破mplus
对于可能
的左偏
本人证明的有效性:
以防你觉得我没有做足够繁琐的推导,我会证明我使用的身份:
首先
Nothing <|> c = c -- left identity <|>
Just d <|> c = Just d -- left bias <|>
第三,其他三个需要更多的工作:
Nothing <*> c = Nothing -- left failure <*>
c <*> Nothing = Nothing -- right failure <*>
Just f <*> Just x = Just (f x) -- success <*>
Nothing c=Nothing——左侧故障
c Nothing=Nothing--正确的失败
Just f Just x=Just(f x)--成功
这来自于定义
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
实例应用程序可能在哪里
纯=返回
()=ap
ap::(单子m)=>m(a->b)->m a->m b
ap=liftM2 id
liftM2::(单子m)=>(a1->a2->r)->M1->M2->MR
liftM2 f m1 m2=do{x1=k=kx
无>>==无
返回=刚刚
所以
mf mx=ap mf mx
=liftM2 id mf mx
=do{f
仅(f x)
因此,如果mf
或mx
为零,则结果也是Nothing
,而如果mf=Just f
和mx=Just x
,则结果是Just(f x)
我一直认为替代法和MonadPlus的唯一法则是幺半群法则。或者,更具体地说,我认为应该有只包含幺半群法则的类型类,任何额外的法则都应该分配给子类。@GabrielGonzalez在实践中,这种事情无论如何都会发生。在我的回答中我证明了基地的一个MonadPlus的例子不符合这些定律。AndrewC:当然应该这么说。人们总是这么说。我们一直在与东亚作战。(谢谢,我回去也确定了我对另一个问题的答案。)哦,我刚刚意识到(读了@PetrPudlák的评论)-我认为我们应该增加关联性,特别是,(ab)c=a(bc)。@AndrewC:我认为这些是附加的非幺半群定律,因为文档中唯一说的是,Alternative
在原始上下文中是明确的,但你是对的,我可能应该更明确一些。(我也可以很容易地制作出一个版本的也许
,带有右偏,既不满足左捕捉也不满足左分布,所以从任何定义来看都不会是MonadPlus,但它会满足另一种选择。)我想知道,从某种意义上来说,是否有可能证明任何东西都是MonadPlus
(幺半群、左零和左分布)或另一个(幺半群、左零和左捕获)已经是的备选方案了
?这将为原始问题提供一个非常笼统的答案。@PetrPudlák我已经研究过了,你的问题(我相信)有一个有趣的答案。你想把它作为一个问题问吗?
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)