我如何确定一个单子是否是可交换的?

18

Control.Monad.List.ListT 的文档说明:“除非参数单子循环,否则不会产生单子。”

  1. 如何确定单子是否具有交换性? 是否有 CommmutativeMonad 类型类? 是否应该有?

  2. 特别地,Control.Monad.RWS.Lazy.RWS 是一种可交换的单子吗?

2个回答

12

一般情况下,如果表达式 a >>= \x -> b >>= \y -> f x y 等同于 b >>= \y -> a >>= \x -> f x y,那么单子是交换的。

换句话说,如果副作用的顺序不重要,那么单子就是可交换的。我们可以替换表达式:

do a <- ma
   b <- mb
   f a b

将参数交换的一个函数。

do b <- mb
   a <- ma
   f a b

大部分许多常见的单子都是可交换的,但您可以通过查看设计并逻辑它或编写一个小程序来测试它以适当的表达式(这自然取决于单子的性质)来确定特定单子是否可交换。据我所知,没有CommutativeMonad类型类。


7
相反地,我认为大多数单子都不是可交换的,除了MaybeReader外,你能列举其他的例子吗? - Tarrasch
1
我经常使用MonadSupply和Random,当然还有像multisets这样的特定无序数据结构的实现。但这是一个公正的批评。 - JeremyKun
根据您的定义,MonadSupply似乎不是可交换的。runSupply (do {a <- supply; b <- supply; return (a - b)}) [1,2]-1 但是 runSupply (do {b <- supply; a <- supply; return (a - b)}) [1,2]1。我的推理有错误吗? - dave4420
3
@Tarrasch提到,ICFP 2009的这次演讲展示了一些很棒的交换单子例子。 - hammar
我以前见过这个。这是一堂很棒的讲座。 - JeremyKun

5

不,没有CommutativeMonad类。而且RWS不是可交换的。要使一个monad是可交换的,必须能够重新排序效果而不会有任何变化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接