我注意到的一件事是Tuple
没有Monad
个实例。
Tuple确实有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)
此时我们知道以任一方式合并mempty
和x
都会产生x
。我们对x
的唯一类型信息是Monoid
。所以基本上只有两个实现是:
join (a, (b, x)) = (a <> b, x)
和
join (a, (b, x)) = (b <> a, x)
其中第二个使ap
和<*>
不一样。
现在我们知道Monad
唯一有效的((,) a)
实例是:
instance Monoid a => Monad ((,) a) where
(a, c) >>= f = let (b, c') = f c in (a <> b, c')
那为什么目前不是这样呢?
答案 0 :(得分:1)
好像这个问题的答案似乎是我必须使用from ("direct:x")
..............
.to(output)
,这会给ghc-8.0.1
一个Tuple
个实例。感谢@Michael指出这一点。