为什么不工作: -
(length [1,2,3,4]) + 3.2
Run Code Online (Sandbox Code Playgroud)
这有效: -
2+3.3
Run Code Online (Sandbox Code Playgroud)
据我所知,在第一种情况下,结果是Int + Float,但在第二种情况下也不一样,或者Haskell自动推断出第二种情况下的类型: - Num + Num而不是那样做在第一种情况下?
Ben*_*Ben 12
Haskell 永远不会为您进行隐式类型转换.+只能在两个相同类型的数字上工作,并且也会将该类型作为结果.+正如您在(length [1,2,3,4]) + 3.2示例中看到的那样,任何其他用法都是错误.
但是,在Haskell中重载了数字文字.2可以是任何数字类型,也3.3可以是任何小数类型.因此,当Haskell看到表达式时,2 + 3.3它可以尝试找到既是"数字"又是"小数"的类型,并将这两个数字视为该类型,以便添加将起作用.
说得更准确,+有类型Num a => a -> a -> a.2它本身就是一种类型Num a => a而且3.3它本身就是一种类型Fractional a => a.将这3种类型放在一起,表达式中的2 + 3.3两个数字都可以给出类型Fractional a => a,因为所有Fractional类型都是Num类型,这也满足了类型+.(如果你将这个表达式输入到GHCi中,则a填入为Double,因为GHC必须将类型默认为某个东西以便对其进行评估)
在表达式中(length [1,2,3,4]) + 3.2,3.2仍然过载(并且在单独的情况下会有类型Fractional a => a).但length [1,2,3,4]有类型Int.由于一边是固定的具体类型,满足类型的唯一方法+是a用另一种类型填充Int,但是违反Fractional约束; 没有办法3.2成为一个Int.所以这个表达式不是很好.
但是,任何Integral类型(其中Int一个)都可以通过应用转换为任何 Num类型fromIntegral(这实际上是整数文字如何2被视为任何数字类型).所以(fromIntegral $ length [1,2,3,4]) + 3.2会工作.
Nic*_*las 10
在第一种情况下,正如您所提到的,length [1,2,3,4]是显式的Int,并且不能隐式转换为Float或转换为任何Fractional实例.而在第二种情况下,没有明确的输入,因此Haskell可以推断出良好的类型是一个实例Fractional.您可以在Haskell 2010报告的相应部分(第6.4.1节)中看到编译器如何处理数字文字.
解决方法: (fromIntegral $ length [1,2,3,4]) + 3.2
整数文字(例如2在第二个示例中)被fromInteger 2编译器隐式地视为.这意味着它们被转换为任何所需的数字类型,因为fromInteger它的返回类型是多态的; 在这种情况下,Float使用.但是,length [1,2,3,4]它是类型Int,而不是文字,因此您需要显式转换其值.
| 归档时间: |
|
| 查看次数: |
294 次 |
| 最近记录: |