为什么 Tuple 没有 Monad 实例?

Why does Tuple not have a Monad instance?

我注意到的一件事是 Tuple 没有 Monad 实例。

但是元组确实有一个 Applicative 实例:

instance Monoid a => Applicative ((,) a)

这已经非常严格地限制了我们可以使 Monad 实例成为什么。

让我们看看我们将获得的类型签名:

instance Monoid a => Monad ((,) a)

join :: Monad m => m (m a) -> m a

join :: Monoid a => (a, (a, b)) -> (a, b)

我们还可以看看 Monad 定律:

join $ f <$> pure x == f x
join $ f <$> (mempty, x) == f x
join (mempty, f x) == f x
join (mempty, (a, b)) == (a, b)

join $ pure <$> x = x
join $ pure <$> (a, b) = (a, b)
join (a, (mempty, b)) = (a, b)

此时我们知道以任何一种方式组合 memptyx 都会得到 x。我们关于 x 的唯一类型信息是它是 Monoid。所以基本上仅有的两个实现是:

join (a, (b, x)) = (a <> b, x)

和:

join (a, (b, x)) = (b <> a, x)

而其中的第二个使得 ap<*> 不一样。

所以现在我们知道 ((,) a) 的唯一有效 Monad 实例是:

instance Monoid a => Monad ((,) a) where
    (a, c) >>= f = let (b, c') = f c in (a <> b, c')

那为什么现在不是这样呢?

好吧,这个问题的答案似乎是我只需要使用 ghc-8.0.1,它确实给 Tuple 一个 Monad 实例。感谢@Michael 指出这一点。