(==)
的类型是Eq a => a -> a -> Bool
,但我可以想象一个更通用的版本Eq a b => a -> b -> Bool
,当类型不匹配时它是假的,并且只是通常的平等类型匹配。为什么不是这样?
答案 0 :(得分:14)
我们可以根据Eq
和Typeable
from Data.Typeable
来定义。我们可以比较Typeable
的事物类型来检查它们是否是同一类型。
(?==) :: (Eq b, Typeable a, Typeable b) => a -> b -> Bool
x ?== y = cast x == Just y
cast
检查一个Typeable
类型的值实际上是否与另一个类型相同。如果输入属于同一类型,则返回Just
;如果类型不同,则返回Nothing
。
以下是一些展示所需行为的例子。
> 7 ?== 7
True
> 7 ?== "hello"
False
> 7 ?== 5
False
> (7 :: Int) ?== (7 :: Integer)
False
答案 1 :(得分:7)
(==) :: Eq a b => a -> b -> Bool
不会像你想象的那样有用。
要确定2参数Eq
的实例,您需要知道两种类型(足以匹配实例)。此==
的所有来电者都需要具体了解a
和b
,或者在其界面中传递约束;然后他们自己的调用者需要知道a
和b
是什么,或者传递约束......在某些时候必须选择Eq
实例,而不是通过约束,包括在编译时了解a
和b
。
那时,你为什么要打扰?如果您知道a
和b
相同,那么单个参数Eq
足以比较它们。如果您知道它们不同,那么您知道答案是False
,并且您不需要任何实例来告诉您。如果您没有知道它们是相同还是不同,那么根据定义,您不了解选择Eq
实例,因此您可以&#39 ; t根本调用==
(或Eq
- 约束函数)!
因此,这不会帮助您从不同的来源获得a
和b
未知类型(实现相等),然后进行比较。他们必须与一个Eq a b
实例结合在一起,这实际上是一个编译时证明它们是否属于同一类型,
@ Cirdec的答案中的Typeable
版本非常不同,而且更有用。每个类型 independentlly 支持Typeable
,其中一个支持单参数Eq
;你可以从两个不同的来源获得这两个值,你不知道它们是否相同,但你知道你可以检查每个值的类型; a
来源必须知道a
以便选择Typeable
个实例,b
来源必须知道b
以便选择Typeable
和Eq
实例,但两个源都不必知道关于其他类型的任何内容,并且没有代码必须同时知道这两种类型,以确定它们是否相同(在编译时间)。 2参数Eq
强制同时知道这两种类型,这会使它几乎毫无价值。
答案 2 :(得分:3)
我认为对你的问题的哲学答案是Haskell本质上类似于数学,当我们把数学对象放在数学对象上并定义数学对象的相等性时,我们通常认为这两个对象属于同一类型。例如。看看如何定义集合等式。
现在,这组自然数是否等于自然数6?或者让我们变得狂野 - 椅子是否等于整数-7?虽然我很想让我的直觉接管和尖叫,但当然不是!#34;我真的不能这么说,因为问题本身是无效的,它是' ; s都是非常不确定的。集合和自然之间的平等是不确定的。主席和整数之间的平等是不确定的。
这是否意味着你无法定义它?不,继续。
但它并不是一种非常流行的方法,因此基础库的选择是非常容易理解的。
作为对您评论的回复,这是正确的。碰巧,集合是如此原始,以至于我们可以用它们代表任何东西。这只是一个例子,如果我们选择其他东西,我也不知道你是否可以同样争论,但不管怎样,让我们骑它。
对于集合A等于集合B,我们需要:
非常简单地说,集合{1,2,3}是否等于7?我不知道,因为说7中存在的元素未定义,问题无效。
但是,让我们采取你的方法,并按照你的说法做:拿7,穿上漂亮的衣服举起它并称之为C组,让我们甚至假设C等于D组表明你是对的。您可以要求7和另一组之间的相等,最终。但我只是想让你注意到在我们做到这一点之前,我们必须如何努力使它成为一个集合。如果可能的话,这正是Haskell想要你做的。使用数学集合,它几乎总是可行的。
因此,无论是在Haskell和数学中,我们(仍然)都无法真正地问:
(a :: Set) == (7 :: Natural)
然而,在Haskell和数学中我们都可以先提升它,这样我们就可以用不同的方式来看待它,然后我们可以问:
(liftN :: Natural -> Set) (7 :: Natural) == (a :: Set)
当然,RHS是集合C.
这个答案的要点是,Haskell只是通过以它的方式定义相等而在常见的数学术语中是惯用的。
答案 3 :(得分:2)
Haskell的观点是,只检查相同类型的两个值的相等性是有意义的,即检查两个不同类型值的相等是没有意义的,很可能意味着你在做错了程序。这就是(==)的类型就是它的原因。
一般来说,这就是在强大的类型系统(如Haskell)中工作的意思。它旨在帮助编写更好,更有意义的程序。