标准的Haskell类型类有哪些法则可以维护?

时间:2013-02-13 19:24:40

标签: haskell interface proof

众所周知,Monad个实例应遵循Monad法律。可能鲜为人知的是Functor个实例应该遵循Functor法则。尽管如此,我觉得写一个优化fmap id == id的GHC重写规则还是相当自信。

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

这些最后几个似乎没有在Haskell 2010报告中指定,也不会有信心编写利用它们的重写规则。但是,有没有共同的图书馆?一个实例如何可以自信地写出病理学?

最后,假设这样一个实例可能存在一个边界,那么每个类型实例必须遵守的法律是否有一个标准的综合资源?


作为一个例子,我将在定义

方面遇到多少麻烦
newtype Doh = Doh Bool
instance Eq Doh where a == (Doh b) = b

它只是难以理解,还是编译器会在任何地方不正确地进行优化?

3 个答案:

答案 0 :(得分:5)

Haskell report提到以下法律:

  • Functor(例如fmap id == id
  • Monad(例如m >>= return == m
  • 积分(例如(x ‘quot‘ y)*y + (x ‘rem‘ y) == x
  • Num(abs x * signum x == x
  • 显示(showsPrec d x r ++ s == showsPrec d x (r ++ s)
  • Ix(例如inRange (l,u) i == elem i (range (l,u))

这就是我能找到的全部。具体来说,关于方程(6.3.1)的部分没有提到任何规律,下一部分也没有提到奥德。

答案 1 :(得分:4)

所有标准实例都不支持我自己对“应该是什么”法律的看法,但我认为

  • Eq应该是等价关系。
  • Ord应该是一个总订单
  • Num应该是一个响铃,fromInteger一个环同态,abs / signum表现得很明显。

许多代码都会假设这些“法律”仍然存在,即使他们没有。这不是Haskell特有的问题,早期的C允许编译器根据代数定律对算术进行重新排序,并且大多数编译器都可以选择重新启用此类优化,即使它们不是当前标准允许的并且可能会改变您的程序结果。

答案 2 :(得分:1)

过去,违反Ix法律会让你做任何事情。这些天我认为他们已经解决了这个问题。更多信息:Does anyone know (or remember) how breaking class laws could cause problems in GHC?