【问题标题】:Third Monoid Law and IO?第三类幺半群定律和 IO?
【发布时间】:2016-07-21 02:18:34
【问题描述】:

看这个IO代码:

Prelude> let e = return () :: IO ()
Prelude> e `mappend` e
Prelude> let y = e `mappend` e
Prelude> :t y
y :: IO ()

编辑显然,据我了解,IO 有一个 Monoid 实例。

但是,为了遵守 Monoid 第三定律,下面的计算不应该为 true 吗?

Prelude> e `mappend` (e `mappend` e) == (e `mappend` e) `mappend` e

<interactive>:14:1: error:
    * No instance for (Eq (IO ())) arising from a use of `=='
    * In the expression:
        e `mappend` (e `mappend` e) == (e `mappend` e) `mappend` e
      In an equation for `it':
          it = e `mappend` (e `mappend` e) == (e `mappend` e) `mappend` e

【问题讨论】:

    标签: haskell


    【解决方案1】:

    The third monoid law 声明 e &lt;&gt; (e &lt;&gt; e) = (e &lt;&gt; e) &lt;&gt; e(为 mappend 使用更易于键入的中缀运算符),不是 e &lt;&gt; (e &lt;&gt; e) == (e &lt;&gt; e) &lt;&gt; e(注意 = 与 @987654327 @)。

    它表达了等价——实际上,表达了mappend 应该是关联的——不要求所有Monoids 也必须是Eq 类型类的实例,== 来自该类型类。

    另一种说法:它表达了关于mappend 函数行为的高级想法,而不是提供应该评估任何特定内容的有效Haskell 代码。

    一些Monoids 类型——例如[()]——也恰好有一个Eq 实例。但有些(比如这里的 IO () 实例)没有,没关系。

    旁注:给IO 提供Eq 实例实际上没有意义,因为几乎不可能确定某个IO () 是否等同于另一个IO ()putStrLn "3" 是否“等于”print 3?它们都具有相同的可观察效果,​​但在一般情况下,运行时究竟如何确定呢?而且您不能说“如果它们产生相同的值,它们是等价的”,因为== 的返回类型必须是IO Bool,而这不是Eq 的正确签名。所以我们只是不给IO 一个Eq 实例,这很好——我想不出一个合理的例子来说明这种实例何时有用。

    另请注意,“IO”没有Monoid 实例(无论如何,这是错误的类型)。您正在使用的mappend 来自Monoid a =&gt; Monoid (IO a) 的实例——即,用于生成本身为Monoids 的类型的IO 配方。 IOMonoid 实例只是底层 Monoid 实例的“背负式”。

    【讨论】:

    • 如果可以编写一个有效的、直观正确的Eq (IO a) 实例,将会非常有用。但是如果你尝试的话,艾伦·图灵会坐在他的坟墓里,给你一顿大骂。
    • @dfeuer 我没有看到问题。毕竟,我们有一个Eq [a] 实例。
    • @dfeuer @ReinHenrichs 当然这是关于可判定性而不是终止? IO a (排序)表示为RealWorld -&gt; (RealWorld, a)。该箭头表示Eq 实例必须决定函数相等,which is equivalent to solving the Halting Problem
    • @BenjaminHodgson,他的观点是无限列表是自然数上的完全通用(可计算)函数。我怀疑这些函数的相等性也是可以确定的。
    猜你喜欢
    • 1970-01-01
    • 2021-11-21
    • 2014-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 2016-08-01
    相关资源
    最近更新 更多