我看到 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/