是有一些原因的前奏没有定义列表单子是这样吗? (注非标准实现>>
)。
instance Monad [] where
m >>= k = concat (map k m)
m >> k = k -- a.k.a. flip const
return x = [x]
fail s = []
我想这个检查对单子的法律,但他们不提>>
。 该Monad
类的定义是这样的:
m >> k = m >>= \_ -> k
这在[]
实例将翻译成这样:
concat (map (\_ -> k) m)
这当然是不等同于flip const
-它们产生,比如说一个明显不同的结果, [1..5] >> return 1
。 但它不是我清楚这个默认的定义是否是实例法律 Monad
必须尊重这一点满足了一些其他法律的,或只是一个默认的实现flip const
实施也将满足。
直观地看,给出的列表单子(“非确定性计算”)的意图 ,它似乎像的另一种定义>>
是一样好,如果不是更好多亏了保证是等于下降到只有一个剪枝。 或者说这句话的另一种方式是,如果我们处理组 ,而非列表 ,两个候选的定义是等价的。 但是我在这里缺少一些细微之处,使flip const
定义错误的列表?
编辑 :ehird的答案抓住一个非常明显的缺陷与上面的,这是它得到了错误的预期结果[] >> k
,应[]
不k
。 不过,我认为这个问题可以修正,这样的定义:
[] >> k = []
_ >> k = k