【发布时间】:2013-01-29 11:04:01
【问题描述】:
众所周知,Monad 实例应该遵循 Monad 定律。 Functor 实例应该遵循函子定律可能不太为人所知。不过,我对编写优化 fmap id == id 的 GHC 重写规则感到相当有信心。
还有哪些其他标准类有隐含的规律? (==) 必须是真正的等价关系吗? Ord 一定要形成偏序吗?总订单?我们至少可以假设它是传递的吗?反对称?
Haskell 2010 报告中似乎没有指定最后几个,我也没有信心编写重写规则来利用它们。但是,是否有任何通用库可以做到?一个实例的病态到什么程度可以自信地写作?
最后,假设这样一个实例的病态程度是有界限的,那么每个类型类实例必须遵守的法律是否有一个标准、全面的资源?
举个例子,我要定义多少麻烦
newtype Doh = Doh Bool
instance Eq Doh where a == (Doh b) = b
仅仅是难以理解还是编译器会在任何地方错误地优化?
【问题讨论】:
-
请注意,
Ord、Num可能会提出相当多听起来合理的法律(包括现有代码默认假设的法律),并且相关类将被 @ 的实例违反987654331@ 和Double。例如,使用 NaN 作为键会破坏Data.Map中的查找,并且精度问题意味着浮点加法不具有关联性。 -
@C.A.McCann 这只是意味着前奏有它不应该的实例!
Float和Double不应是Eq的成员 -
@PhilipJF:一方面,我同意。但是他们的
Num实例稍好一些,并且按照这一论点得出其逻辑结论会导致删除所有使浮点类型实际有用的实例。顺便说一句,I gave a demonstration of how broken theirOrdinstance is in an old post. -
@C.A.McCann 我可以接受这些实例,只要这些类型仅限于特殊的“性能”导向模块。为什么
Prelude中有浮点类型?如果你真的需要一个浮点数(而不是一个比率或一个建设性的实数),你可能知道你在做什么。 -
可能值得注意的是,在标准 ML 中,reals are not equality types。因此,至少另一种语言更注重正确性而不是实用性。 :)