【问题标题】:Why does Tuple not have a Monad instance?为什么 Tuple 没有 Monad 实例?
【发布时间】:2016-07-16 20:33:20
【问题描述】:

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

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

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

这已经极大地限制了我们可以使 Monad 实例成为的内容。

让我们看看我们会为 join 得到的类型签名:

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

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

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

我们也可以看看单子定律:

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&lt;*&gt; 不一样。

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

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

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

【问题讨论】:

  • 我猜这是 ghc-8.1 的新功能 - ghciinstance Monoid a =&gt; Monad ((,) a) -- Defined in ‘GHC.Base’
  • 一个疯狂的猜测:因为它不够通用?这可能是Set没有的原因……
  • Set 没有单子实例,因为不存在满足单子定律的实例。 ((,) a) 的提议实例是守法的,我认为是唯一可能的守法实例,因此创建它是有意义的。
  • 我通常只使用the Writer Monad...
  • @ThreeFx 这是尽可能通用的。此外,根本没有实例将更具限制性。而且,正如 Michael 所提到的,这个实例已经存在于最新的稳定版 GHC 中。

标签: haskell tuples monads


【解决方案1】:

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

【讨论】:

  • 8.1 还没有出来;他的意思是8.0.1。实例可以在here找到。
猜你喜欢
  • 2016-01-18
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-06
  • 1970-01-01
相关资源
最近更新 更多