我看到Haskell允许比较不同的数字类型:
*Main> :t 3
3 :: Num t => t
*Main> :t 3.0
3.0 :: Fractional t => t
*Main> 3 == 3.0
True
Run Code Online (Sandbox Code Playgroud)
Eq数值类型实例的源代码在哪里?如果我创建一个新类型,例如ComplexNumber,我可以扩展==为它工作吗?(我可能希望没有虚部的复数可能等于实数.)
lef*_*out 10
"Haskell允许比较不同的数字类型"不,它没有.Haskell实际允许的是由相同的文字定义的不同类型.特别是,你可以做到
Prelude> let a = 3.7 :: Double
Prelude> let b = 1 :: Double
Prelude> a + b
4.7
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
现在,Double不是最常用的类型a或者b.事实上,所有数字文字都是多态的,但在任何操作(如相等比较)发生之前,这种多态类型需要固定到具体的单态类型.喜欢,
Prelude> (3.0 :: Double) == (3 :: Double)
True
Run Code Online (Sandbox Code Playgroud)
因为==,与你的前提相反,实际上要求双方都有相同的类型,你可以省略任何一方的签名而不改变任何东西:
Prelude> 3.0 == (3 :: Double)
True
Run Code Online (Sandbox Code Playgroud)
事实上,即使没有任何类型的注释,GHCi仍然会将双方视为Double.这是因为类型默认 - 在这种特殊情况下,Fractional是对共享数字类型的最强约束,而对于Fractional默认类型是Double.OTOH,如果双方都是完整的文字,那么GHCi就会选择Integer.例如,这有时会产生影响
Prelude> 10000000000000000 == 10000000000000001
False
Run Code Online (Sandbox Code Playgroud)
但
Prelude> 10000000000000000 ==(10000000000000001 :: Double)
True
Run Code Online (Sandbox Code Playgroud)
因为在后一种情况下,最后的1在浮点错误中丢失.
| 归档时间: |
|
| 查看次数: |
88 次 |
| 最近记录: |