Prelude> let c=[1.0,2.0]
Prelude> :t c
c :: Fractional t => [t]
我期待" c"是Num或Float的列表。为什么分数?在Haskell中是否有任何隐式类型转换?
答案 0 :(得分:4)
你可以实现它:
> :set -XNumDecimals
> let c=[1.0,2.0]
> :t c
c :: Num t => [t]
“为什么Fractional
”的答案基本上是“因为报告是这样说的”:
float → decimal . decimal [exponent] | decimal exponent
浮动文字表示将
fromRational
应用于Rational
类型的值(即Ratio Integer
)。给出了类型:fromInteger :: (Num a) => Integer -> a fromRational :: (Fractional a) => Rational -> a
整数和浮动文字的分别为
(Num a) => a
和(Fractional a) => a
。
我猜测报告是这样说的,因为这是一个很好的简单规则来解释:没有点/指数,它是Num
- 多态,是点/指数,它是Fractional
- 多态。
两个相关位是:
https://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-190002.5
https://www.haskell.org/onlinereport/haskell2010/haskellch6.html#x13-1360006.4.1
答案 1 :(得分:3)
Haskell中没有隐式类型转换。数字文字具有多态类型。
> :t 3
3 :: Num a => a
> :t 3.5
3.5 :: Fractional a => a
标准Haskell将带小数点的任何数字视为小数,即使小数位数都是0.它还将用科学计数法写成的任何数字视为小数。如果您愿意,可以使用GHC扩展来使用这种表示形式更具多态性。
至于标题中的问题,Float
是具体类型(Float :: *
),而Fractional
是类型类(Fractional :: * -> Constraint
)。您可以编写许多适用于各种Fractional
或RealFrac
或RealFloat
类型的函数,而无需担心确切的表示形式。
旁注:Float
是一种特殊用途类型,适用于专门的算法,格式等,以及某些情况,其中数组的紧凑表示比精度或数值稳定性更重要。当你想要浮点数时,你通常想要的是Double
。