Haskell中`==`的类型应为`Eq ab => a - > b - > Bool`

dav*_*k01 6 haskell types equality typeclass

类型(==)Eq a => a -> a -> Bool但我可以想象一个更通用的版本Eq a b => a -> b -> Bool,当类型不匹配时是假的,并且只是类型匹配时通常的相等类型.为什么不是这样?

Cir*_*dec 14

我们可以定义,在这两个方面Eq,并TypeableData.Typeable.我们可以比较Typeable要检查它们是同一类型的事物类型.

(?==) :: (Eq b, Typeable a, Typeable b) => a -> b -> Bool
x ?== y = cast x == Just y
Run Code Online (Sandbox Code Playgroud)

cast检查一种Typeable类型的值实际上是否与另一种类型相同.Just如果它们是相同类型或Nothing类型不同,则返回输入.

以下是一些展示所需行为的示例.

> 7 ?== 7
True

> 7 ?== "hello"
False

> 7 ?== 5
False

> (7 :: Int) ?== (7 :: Integer)
False
Run Code Online (Sandbox Code Playgroud)


Ben*_*Ben 7

(==) :: Eq a b => a -> b -> Bool 不会像你想象的那么多.

要确定2参数的实例Eq,您需要知道两种类型(足以匹配实例).任何此类调用者==都需要具体知道ab在其接口中传递约束; 然后自己呼叫者要么需要知道什么是ab是,或通过对约束....在某些点上Eq的实例必须选择,而不是通过限制规定,而且包括了解ab 在编译时.

那时,你为什么要打扰?如果你知道a并且b是相同的,那么一个参数Eq足以比较它们.如果你知道它们是不同的,那么你就知道答案是False,你不需要任何实例来告诉你.如果你知道它们是相同还是不同,那么根据定义你不知道选择一个Eq实例,所以你根本不能调用==(或者是一个Eq约束函数)!

因此,这不会帮助您从不同的源获取一个ab未知类型(实现相等),然后比较它们.他们将不得不与一个Eq a b实例结合在一起,这实际上是一个编译时证明它们是否是同一类型,

Typeable@ Cirdec答案中的版本非常不同,而且更有用.这里每种类型都独立支持Typeable,其中一种支持单参数Eq; 您可以从两个不同来源获取这两个值,但不知道它们是否相同,但您知道可以检查每个值的类型; 在a源已经知道a不够好,选择一个Typeable实例和b源已经知道b不够好选择TypeableEq情况,但既不源有了解的任何其他类型,并且没有代码已经知道这两种类型的一次不够好判断它们是否相同(在编译时).2参数Eq强制同时在某个地方知道这两种类型,这将使​​它几乎毫无价值.

  • 你可能想提一下Cirdec的(不可避免的)`Typeable`约束不是免费的 - 除非它们在编译时专门化(所以你不需要`?==`),它们涉及传递两个额外的词典运行. (2认同)