众所周知,Monad
个实例应遵循Monad法律。可能鲜为人知的是Functor
个实例应该遵循Functor法则。尽管如此,我觉得写一个优化fmap id == id
的GHC重写规则还是相当自信。
其他标准类有哪些隐含法律? (==)
必须是真正的等价关系吗? Ord
是否必须形成部分订单?总订单?我们至少可以假设它具有传递性吗?反对称?
这些最后几个似乎没有在Haskell 2010报告中指定,也不会有信心编写利用它们的重写规则。但是,有没有共同的图书馆?一个实例如何可以自信地写出病理学?
最后,假设这样一个实例可能存在一个边界,那么每个类型实例必须遵守的法律是否有一个标准的综合资源?
作为一个例子,我将在定义
方面遇到多少麻烦newtype Doh = Doh Bool
instance Eq Doh where a == (Doh b) = b
它只是难以理解,还是编译器会在任何地方不正确地进行优化?
答案 0 :(得分:5)
Haskell report提到以下法律:
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))
)这就是我能找到的全部。具体来说,关于方程(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?