Haskell 中有啥有趣的交换单子吗?

Posted

技术标签:

【中文标题】Haskell 中有啥有趣的交换单子吗?【英文标题】:Are there any interesting commutative monads in Haskell?Haskell 中有什么有趣的交换单子吗? 【发布时间】:2014-06-22 22:02:36 【问题描述】:

直到我今天编辑它,Haskell Wiki claimed Maybe 是一个可交换的 monad(实际上,我认为它仍然在某个地方声明它)。这显然是错误的,因为

do a <- Nothing; b <- undefined; return (a,b) === Nothing

同时

do b <- undefined; a <- Nothing; return (a,b) === undefined

这种可交换性的失败实际上在实际代码中相当重要:程序员依赖于这样一个事实,即计算将在到达Nothing 时立即停止。

这留下了(在 Haskell Wiki 上描述为可交换的单子中)只有 Reader 单子,它似乎没有做任何非常令人兴奋的事情。这在我的脑海中提出了一个问题,即 Haskell 中是否存在与 Reader 大不相同的可交换 monad,除了 of Reader 的限制。

编辑

我刚刚意识到也可以使受限的Writer monad 成为可交换的——它需要在一些可交换的幺半群中累积值。还是没意思。

【问题讨论】:

undefined 有点作弊。请参阅:cse.chalmers.se/~nad/publications/…。你声称一个表达式等于undefined。但是undefined 不等于任何东西。这不是一个值。如果不解决停机问题,就无法比较底部。 @nomen, undefined 没有 == 任何东西,但在一般意义上(基于指称语义)通常被认为等于任何其他底值。 是的,将所有底部设置为相等并不会使我的观点无效。事实上,如果你修改了这种等价关系,Haskell 是完全的(正如论文的观点)。现在,我的观点是,这是一种“作弊”,因为您使用的语义与隐含使用的语句(“也许是可交换的”)不同。 @nomen,我不知道你在说什么。等于所有底部仍然不能使Nothing === bottom 如果排除底部,则不包括底部... 【参考方案1】:

这样的陈述有时会隐含“忽略底部”的要求,这可能就是其中之一 那些案件。如果我们忽略底部,它是可交换的。不过,最好明确表达该要求,因为它可能变得很重要。

如果我们确实忽略底部,那么Maybe 也是一个可交换的 Monad。当然,正如您在问题中提到的那样,从实践上讲,底部很重要,因此最好注意它们存在的非交换性。

【讨论】:

我认为可以说任何关于 Haskell 的分类声明(即关于 Haskell 中的分类理论的声明)都隐含地忽略了底部。 在很多情况下,“破底”的情况是一件痛苦的事情;对于Maybe,这正是我们想要的。是的,很高兴认识到,当您可以证明没有一个动作是底部时(并且对其结果的任何模式匹配都不会强制底部),那么人们可以交换这些动作以提高效率/清晰度。但是当你到达那里时,你会更深入地研究细节,而不是“交换单子”的概念。 @nomen:对。我想说的是,Haskell 中即使有底部也成立的分类语句是例外情况(反之亦然),因为它必须以这种方式通常不可能的方式利用非严格评估. @dfeuer 好吧,monad 来自范畴论,所以交换 monad 将是一个范畴概念。但这不是我的重点。我的意思是,不管范畴论如何,很多时候当你试图以正式的方式(例如展示交换性)来推理 Haskell 程序时,底部可能会妨碍你。有时,查看除了涉及底部之外的属性会很方便,因为底部无论如何都会弄乱很多事情。检查底部究竟会在什么时候搞砸(您可以评估多远)也很有用。 @dfeuer 要证明即使有底部也适用平等法,您不仅要证明您打算证明的法律,还必须证明一切都得到了完全相同的评估平等双方的时间通常是一种痛苦,它排除了一些其他有用的法律。此外,如果一个等式正常成立,但对于底部不成立,我可能会更担心哪种方式对于长时间计算更有效,而不是担心底部的行为。【参考方案2】:

set monad 具有可交换性,并且在 IMO 中很有趣。

【讨论】:

哦,哈哈。我以前没见过set-monad。这是解决问题的巧妙方法。 想详细说明@leftaroundabout? @gallais:你的意思是为什么它是可交换的,或者为什么有些人可能不认为它是一个单子? @leftaroundabout 后者 @gallais: 好吧,所有的法律都只适用于你最终用run 得到的东西(或与== 比较),而内部表示基本上只是一个原始语法树,因此当您切换到编写某些表达式的等效方式时会发生变化。这对我来说很好,但是apparently there isn't a universal consensus about which sense of equalness should be used for monad laws etc..

以上是关于Haskell 中有啥有趣的交换单子吗?的主要内容,如果未能解决你的问题,请参考以下文章

Haskell概率单子的类型类问题

如何在 Haskell 中构建一个不确定的状态单子?

FFI 可以处理数组吗?如果是这样,怎么做?

Haskell趣学指南

如果你违反了单子法则,你会发生啥?

我想我找到了一个“不存在的单子”