【问题标题】:Why isn't `join` part of the `Monad` class [duplicate]为什么`join`不是`Monad`类的一部分[重复]
【发布时间】:2015-07-22 00:48:00
【问题描述】:

众所周知,(>>=) 可以使用fmapjoin 实现,而join 可以使用>>= 实现。我们是否有任何理由不定义包含joinMonad 类并使用以下默认定义?

join x  = x >>= id
x >>= f = join $ f <$> x

这将允许一个最小定义只包括(&gt;&gt;=)join,而不是强制(&gt;&gt;=)。考虑到类别理论倾向于join,这可能会有所帮助。

反对修改类的通常论点是我们破坏了向后兼容性。但是,在这种情况下,这不会发生 - 我们只添加了使用 join 定义 Monad 的可能性。

【问题讨论】:

  • 如你所说,(&gt;&gt;=) = join . fmap,但在 GHC 7.10 之前,Monad不是自动成为仿函数。从这个意义上说,我们在bind 中定义了joinfmap。有时实现&gt;&gt;= 也比加入要容易得多。尝试为解析器/状态函子做这件事。
  • @AJFarmar 我不认为(&gt;&gt;=) = join . fmap 有效。争论被颠倒了,还有一些其他的问题。但好点!
  • 啊,你是对的,它实际上是(join .) . flip fmap,但正如你所说,这个想法就在那里。
  • @AJFarmar,最好选择=&lt;&lt;,它更符合世界其他地区。 f =&lt;&lt; m = join (fmap f m)(=&lt;&lt;) f = join . fmap f.

标签: haskell monads


【解决方案1】:

Applicative-Monad proposal(它已进入 GHC 7.10)本应发生这种情况。但是,GHC 中有 a technical issue 涉及 type roles,它已无限期推迟您建议的实施。

【讨论】:

  • 这是排除join的可怕理由。它应该是 Monad 类的一部分。
  • @augustss,这是一个 sad 的原因,而不是一个 bad 的原因。能够对 monad 使用广义的新类型推导和强制转换是一件好事。
  • @dfeuer 就像你说的那样,但可以简单地独立定义join,然后使用我上面指出的身份(&gt;&gt;=) = (join .) . flip fmap,所以问题不大。
  • @dfeuer 我认为这是一个不好的理由。 GNTD 是,IMO,用不健全的 hack 实现的。而现在他们已经构建了一个精心设计的类型系统来让 hack 发出声音,而且每个人都必须为此付费。
  • @dfeuer 有两个问题,如何决定接受哪个 GNTD 以及如何进行零成本强制。为了确定新类型派生是否可以接受,我认为编译器应该构造一个实例声明并确保它进行类型检查。这将排除坏情况,但也会排除一些好的情况。我愿意承担这个损失。要获得零成本强制,您仍然可以像 ghc 那样使用强制,但我更喜欢编译器识别身份函数并在内部用强制替换它们。我认为当前的 ghc 情况是抽象泄漏。
猜你喜欢
  • 1970-01-01
  • 2012-08-26
  • 1970-01-01
  • 2021-07-29
  • 2018-02-18
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多