haskell - 数字类型的相等性如何工作?

标签 haskell typeclass

我看到 Haskell 允许比较不同的数字类型:

*Main> :t 3
3 :: Num t => t
*Main> :t 3.0
3.0 :: Fractional t => t
*Main> 3 == 3.0
True
Eq的源代码在哪里数字类型的实例?如果我创建一个新类型,例如 ComplexNumber,我可以扩展 ==为它工作? (我可能希望没有虚部的复数可能等于实数。)

最佳答案

“Haskell 允许比较不同的数字类型”不,它不允许。 Haskell 实际上允许由相同的文字定义不同的类型。特别是,你可以做

Prelude> let a = 3.7 :: Double
Prelude> let b = 1   :: Double
Prelude> a + b
4.7

OTOH,如果我用冲突类型明确声明这些,添加将失败:
Prelude> let a = 3.7 :: Double
Prelude> let b = 1   :: Int
Prelude> a + b

<interactive>:31:5:
    Couldn't match expected type ‘Double’ with actual type ‘Int’
    In the second argument of ‘(+)’, namely ‘b’
    In the expression: a + b

现在,Double不是 a 最通用的类​​型或 b .事实上,所有数字文字都是多态的,但在任何操作(如相等比较)发生之前,需要将这种多态类型固定为具体的单态类型。喜欢,
Prelude> (3.0 :: Double) == (3 :: Double)
True

因为 == ,与您的前提相反,实际上要求双方具有相同的类型,您可以省略任何一方的签名而无需更改任何内容:
Prelude> 3.0 == (3 :: Double)
True

事实上,即使没有任何类型注解,GHCi 仍然会将双方视为 Double .这是因为 type defaulting – 在这种特殊情况下,Fractional是对共享号码类型的最强约束,对于 Fractional , 默认类型为 Double . OTOH,如果双方都是整数文字,那么 GHCi 会选择 Integer .这有时会有所作为,例如
Prelude> 10000000000000000 == 10000000000000001
False


Prelude> 10000000000000000 ==(10000000000000001 :: Double)
True

因为在后一种情况下,最后的 1 在浮点错误中丢失。

关于haskell - 数字类型的相等性如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38707495/

相关文章:

c - Haskell:使用对变量的最后引用来有效地创建一个新变量

haskell - 求和类型与 Maybes 的记录

haskell - `join` 是如何在 Maybe/List monad 中实现的?

haskell - 无法将预期类型 `Text' 与实际类型 `[Char]' 匹配

haskell - 一次更新两个记录字段时类型变量不明确(但更新一个记录字段时则不然!)

haskell - 为什么 Stack 选择 ghc 7.10,即使有 ghc8 的 lts?

haskell - 为什么实例只匹配头部?

haskell - 从上下文中猜测 Num 的正确实例

haskell - 使用 runReaderT 消除 MonadReader 约束

haskell - 具有不包含等式/对称性但包含不等式/不对称性的定律的类型类