【问题标题】:What's the difference between "float" and "fractional" in Haskell?Haskell中的“float”和“fractional”有什么区别?
【发布时间】:2016-05-16 05:53:03
【问题描述】:
Prelude> let c=[1.0,2.0]
Prelude> :t c
c :: Fractional t => [t]

我希望“c”是 Num 或 Float 的列表。为什么是分数? Haskell 中是否有任何隐式类型转换?

【问题讨论】:

  • 好吧,.0 表示数字的 小数 部分(即使在这种情况下是 0)。 [1.5] 的类型是什么?它不能是Num,因为如果它是Num,它必须可以转换为,比如说,Int,但是没有独特的合理方法可以做到这一点(四舍五入?四舍五入?四舍五入?四舍五入奇怪?)。此外,您不希望1.0 具有Num 类型,而1.1 具有Fractional 类型......一个轻微的错字可能会改变程序中太多的东西。因此报告中的简单规则。

标签: class haskell types


【解决方案1】:

Haskell 中没有隐式类型转换。数值字面量具有多态类型。

> :t 3
3 :: Num a => a

> :t 3.5
3.5 :: Fractional a => a

标准 Haskell 将任何带小数点的数字视为小数,即使小数位全为 0。它还将以科学记数法书写的任何数字视为小数。如果您愿意,可以使用一个 GHC 扩展来使此类表示更加多态。

关于你标题中的问题,Float 是具体类型(Float :: *),而Fractional 是类型类(Fractional :: * -> Constraint)。您可以编写许多函数来处理各种 FractionalRealFracRealFloat 类型,而不必担心确切的表示。

旁注:Float 是一种特殊用途的类型,用于专门的算法、格式等,以及在某些情况下,数组的紧凑表示比精度或数值稳定性更重要。当你想要浮点时,你通常想要的是Double

【讨论】:

    【解决方案2】:

    你可以做到:

    > :set -XNumDecimals
    > let c=[1.0,2.0]
    > :t c
    c :: Num t => [t]
    

    “为什么Fractional”的答案基本上是“因为报告这么说”:

    float →   decimal . decimal [exponent]
          |   decimal exponent
    

    浮动文字代表fromRationalRational 类型的值(即Ratio Integer)的应用。给定类型:

    fromInteger  :: (Num a) => Integer -> a  
    fromRational :: (Fractional a) => Rational -> a
    

    整数和浮动文字的类型分别为(Num a) => a(Fractional a) => a

    我猜报告是这么说的,因为它是一个很好的简单解释规则:没有点/指数,它是 Num-polymorphic,是的点/指数,它是 Fractional-polymorphic。

    两个相关位是:
    https://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-190002.5
    https://www.haskell.org/onlinereport/haskell2010/haskellch6.html#x13-1360006.4.1

    【讨论】:

    • @Bakuriu:真的吗?我的 GHC-7.10 确实可以识别它; -XNumDecimals 实际上从 7.8 开始可用。
    • @leftaroundabout 嗯,现在可以了。我猜我第一次尝试时打错了。
    猜你喜欢
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 2019-07-14
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多