12

为什么没有 monad 实例Control.Applicative.Const?以下定义是正确的,还是违反了单子定律?

instance Monoid a => Monad (Const a) where
  return _ = Const mempty
  (Const x) >>= _ = Const x

你能想到任何有用的应用程序吗?

4

2 回答 2

22

它违反了左身份法则return x >>= f必须相同f x,但要考虑f x = Const (x + 1)

于 2012-07-17T20:35:30.903 回答
0

ehird 的回答解释了问题中的实例有什么问题。这里有一个更深入的解释,说明为什么没有其他实例可以工作,即使您要选择除 之外的约束Monoid,除非该类型只有一个居民(例如,())。任何给定类型要么有零个居民,要么有一个居民,要么至少有两个居民。

案例1:零居民

你可以写这个总函数,一个明显的矛盾:

{-# LANGUAGE EmptyCase #-}
oops :: void
oops = case getConst (return () :: Const TheEmptyType ()) of {}
案例2:一名居民

这种特殊情况实际上是可能的:它与Proxy. 为了完整起见,这里是:

instance Monad (Const ()) where
    return _ = Const ()
    Const () >>= _ = Const ()
案例 3:至少有两个居民

xy成为您选择的类型的两个不同的居民。编写这个辅助函数:

f False = Const x
f True = Const y

现在考虑左恒等律的这两个实例:

return False >>= f = f False
return True >>= f = f True

通过参数化,没有办法实现returnandreturn Falsereturn True不同的,所以你最终得到相同的值必须等于Const xand Const y,这是一个矛盾,因为我们之前说过xandy是不同的。

于 2021-11-25T23:34:39.640 回答