为什么`>>`的list monad方法定义为`flip const`? [英] Why isn't the list monad method for `>>` defined as `flip const`?

查看:122
本文介绍了为什么`>>`的list monad方法定义为`flip const`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Prelude没有像这样定义列表monad有什么原因吗? (注意>> 的非标准实现。)

  instance Monad []其中
m>> = k = concat(地图km)
m>> k = k - aka flip const
return x = [x]
fail s = []

我试图根据monad法律进行检查,但他们没有提及>> Monad 类定义是这样的:

  m>>> k = m>> = \\ __  - > k 

其中 [] 转换为:

  concat(map(\_  - > k)m)

当然不等于 flip const - 它们会产生明显不同的结果例如, [1..5]>>返回1 。但是,我不清楚这个默认定义是否是 law Monad 的实例必须是尊重的,或者只是一个满足其他一些规则的默认实现 flip const 实现也会满足。



直观上,给定 列表monad(非确定性计算),看起来像>>< / code>的替代定义一样好,如果不是更好,等于只有一个。或者另一种说法是,如果我们正在处理集合而不是列表,那么这两个候选定义将是等价的。但是我在这里遗漏了一些微妙的东西,这使得 flip const 定义在列表中是错误的吗?

编辑:ehird的答案在上面出现了一个非常明显的缺陷,那就是它得到了错误的预期结果 []>> k ,它应该是 [] ,而不是 k 。不过,我认为这个问题可以修改为这个定义:

  []>> k = [] 
_>> k = k


解决方案

a> ;> b 必须始终等于 a>> = const b ;它只在 Monad 类中,所以你可以定义一个更高效的(但是在语义上等价的)版本。这就是为什么它不是monad法的一部分:它不是monad定义的一部分,只是typeclass(如 fail )。



不幸的是,我无法在明确声明的基础包的文档中找到任何地方,但我认为旧版本可能定义了(>>)> Monad typeclass。



值得一提的是,您定义(>>)打破了monad用于非确定性计算的列表。由于 [] 用于表示失败,因此 []>> m 必须始终为 [] ;在用尽所有可能的分支之后,你无法继续!这也意味着这两个方案:

  do {m; ...} 
do {_< - m; ...}

可能在行为上有所不同,因为前者使用 >>)< / code>以及后者< code>(>> =)。 (请参阅 Haskell 2010 Report 。)


Is there some reason why the Prelude doesn't define the list monad like this? (Note the non-standard implementation of >>.)

instance  Monad []  where
    m >>= k          = concat (map k m)
    m >> k           = k                 -- a.k.a. flip const
    return x         = [x]
    fail s           = []

I tried checking this against the monad laws, but they don't mention >>. The Monad class definition is this:

m >> k = m >>= \_ -> k

which in the [] instance would translate to this:

concat (map (\_ -> k) m)

which is of course not equivalent to flip const—they produce an obviously different results for, say, [1..5] >> return 1. But it's not clear to me whether this default definition is a law that instances of Monad must respect, or just a default implementation that satisfies some other law that the flip const implementation would also satisfy.

Intuitively, given the intent of the list monad ("nondeterministic computations"), it seems like the alternative definition of >> would be just as good, if not better thanks to pruning branches that are guaranteed to be equal down to just one. Or another way of saying this is that if we were dealing with sets instead of lists, the two candidate definitions would be equivalent. But am I missing some subtlety here that makes the flip const definition wrong for lists?

EDIT: ehird's answer catches a very obvious flaw with the above, which is that it gets the wrong intended result for [] >> k, which should be [], not k. Still, I think the question can be amended to this definition:

[] >> k = []
_ >> k = k

解决方案

a >> b must always be equivalent to a >>= const b; it's only in the Monad class so that you can define a more efficient (but semantically equivalent) version. That's why it's not part of the monad laws: it's not really part of the definition of a monad, only the typeclass (like fail).

Unfortunately, I can't find anywhere in the documentation for the base package where this is stated explicitly, but I think older versions may have defined (>>) outside of the Monad typeclass.

For what it's worth, your definition of (>>) breaks the list monad's use for nondeterministic computations. Since [] is used to represent failure, [] >> m must always be []; you can't continue on after you've exhausted all possible branches! It would also mean that these two programs:

do { m; ... }
do { _ <- m; ... }

could differ in behaviour, since the former desugars with (>>) and the latter with (>>=). (See the Haskell 2010 Report.)

这篇关于为什么`&gt;&gt;`的list monad方法定义为`flip const`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆