Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如果我们在创建数据类型时导出Ord而不是Eq,会发生什么?_Haskell - Fatal编程技术网

Haskell 如果我们在创建数据类型时导出Ord而不是Eq,会发生什么?

Haskell 如果我们在创建数据类型时导出Ord而不是Eq,会发生什么?,haskell,Haskell,我理解,在haskell中,如果我们制作一个派生Ord的数据类型,那么它也应该派生Eq,但为什么我们必须在定义中明确地写下这两个数据类型?一个人可以合理地派生出Ord,但手动实例化Eq: data Foo = Foo deriving Ord instance Eq Foo where _ == _ = True 我想不出一个地方可以立即使用,但没有理由阻止它。你需要编写Eq,原因与你必须在为Ord编写实例之前(或至少在编译之前)为Eq编写实例相同。可以推断出一个,但该属性并不适用于所

我理解,在haskell中,如果我们制作一个派生Ord的数据类型,那么它也应该派生Eq,但为什么我们必须在定义中明确地写下这两个数据类型?

一个人可以合理地派生出
Ord
,但手动实例化
Eq

data Foo = Foo deriving Ord
instance Eq Foo where
    _ == _ = True

我想不出一个地方可以立即使用,但没有理由阻止它。

你需要编写
Eq
,原因与你必须在为
Ord
编写实例之前(或至少在编译之前)为
Eq
编写实例相同。可以推断出一个,但该属性并不适用于所有类型类上下文,因此需要显式


编译器可以很容易地知道派生
Eq
(这可能是相当无害的),但是如果没有明确要求就有一个typeclass实例,可能会引起一些意外。如果它发生在更复杂的类型类上,这可能会非常混乱。

还有一个更灵活的定义:
datafoo=。。。派生(Ord);实例Eq Foo,其中x==y=compare x y==Eq
。GHC然后有效地自动生成这两个实例。(当然,
派生(Eq,Ord)
已经这样做了,或多或少,所以这可能不是非常有用。)更大的问题是,有时超类可以基于几个子类中的任何一个子类派生。在这种情况下,它应该选择哪一个?例如,
Functor
可以从
Applicative
Traversable
Comonad
派生。但是,这些都不能在数据声明中自动派生?@Tesseract、
Traversable
Functor
都可以使用适当的扩展名。当然,这意味着dfeuer的模糊性在实践中不可能发生,但这似乎更像是巧合,原则上这是一个值得思考的问题。有时,您可以提供比派生实例快得多的
Eq
实例。字符串(和其他内部结构)背后的思想是,您可以在O(1)时间内比较它们是否相等。我可以看到这样一种情况,但略有不同,您可能需要一个标准的
Ord
实例,而不是一个特殊的
Eq
实例。