9

众所周知,Monad实例应该遵循单子定律。Functor实例应该遵循函子定律可能不太为人所知。尽管如此,我对编写优化fmap id == id.

还有哪些其他标准类有隐含的法律?(==)必须是真正的等价关系吗?Ord一定要形成偏序吗?总订单?我们至少可以假设它是传递的吗?反对称?

最后几个似乎没有在 Haskell 2010 报告中指定,我也没有信心利用它们编写重写规则。但是,是否有任何通用库可以做到?一个人可以自信地写出一个多么病态的例子?

最后,假设这样一个实例的病态程度是有界限的,每个类型类实例必须遵守的法律是否有一个标准的、全面的资源?


例如,我要定义多少麻烦

newtype Doh = Doh Bool
instance Eq Doh where a == (Doh b) = b

仅仅是难以理解还是编译器会在任何地方错误地优化?

4

3 回答 3

5

Haskell 报告提到了以下法律:

  • 函子(例如fmap id == id
  • 单子(例如m >>= return == m
  • 积分(例如(x ‘quot‘ y)*y + (x ‘rem‘ y) == x
  • 数 ( abs x * signum x == x)
  • 显示 ( showsPrec d x r ++ s == showsPrec d x (r ++ s))
  • 九(例如inRange (l,u) i == elem i (range (l,u))

这就是我能找到的。具体来说,关于 Eq (6.3.1) 的部分没有提到任何定律,下一个关于 Ord 的部分也没有提到。

于 2013-02-16T11:06:26.750 回答
4

并非所有标准实例都支持我对法律“应该是”的看法,但我认为

  • Eq应该是等价关系。
  • Ord应该是一个总订单
  • Num应该是一个环,具有fromInteger环同态,并且abs/signum以明显的方式表现。

许多代码将假定这些“法律”成立,即使它们不成立。这不是 Haskell 特定的问题,早期的 C 允许编译器根据代数定律重新排序算术,并且大多数编译器可以选择重新启用这种优化,即使它们不受当前标准的允许并且可能会改变您的程序结果。

于 2013-02-13T20:19:14.750 回答
1

过去,违反 Ix 定律会让你做任何事情。这些天我认为他们已经解决了这个问题。更多信息在这里:有谁知道(或记得)违反阶级法会如何导致 GHC 出现问题?

于 2013-02-28T19:23:46.583 回答