【问题标题】:What's the difference between the classes Floating and Fractional in Haskell?Haskell 中的 Floating 和 Fractional 类有什么区别?
【发布时间】:2017-06-17 06:46:11
【问题描述】:

Haskell 中的 FloatingFractional 类有什么区别?

【问题讨论】:

  • 他们在前奏曲中紧挨着。
  • 你到底想说什么?
  • 文档上真的没有信息吗?
  • 这个问题不需要更多信息。
  • 文档确实很差

标签: haskell floating-point fractions


【解决方案1】:

非常粗略:

  • Fractional 是可以表示(精确地或至少近似地)任何rational number 的类型。它可能也可以随意表示其他数字,但这并不重要。
    换句话说,它只是具有除法运算的数字类型类;由于它是Num 的子类,因此类型必须包含有理数。

  • Floating 是在柯西意义上的限制下封闭的数字类型类,即complete spaces。这是进行任何类型的微积分所必需的。 Floating 类的方法是在数学上定义为极限的函数,即无限和(这是泰勒级数的部分和序列的极限)。
    因为您可以将实数定义为序列的极限有理数,因为Floating 又是Fractional 的子类,所以任何Floating 类型都能够表示(再次,至少到一个像样的近似)任何real number

可视化差异的一个好方法是通过拓扑:Floating 类型是 connected spaces,即它们形成一个连续体。这对浮点数意味着:每个值都被理解为实数的整个区间(因为浮点总是有一些不确定性)。当您将这些间隔并排放置时,您将整个实数平铺(至少到 ±10300)而没有间隙。

相比之下,一些Fractional 类型没有连接。特别是,Rational 可以完全表示它的所有(有理数)值,因此每个值只是一个“无限小点”。您永远无法用这些点覆盖整条实线,也无法计算像 sinlog 这样的函数,因为这些函数的结果通常是非有理实数。


值得思考一下这个“体面的近似值”是什么意思。 Haskell 标准没有定义这一点。这个关于每个浮点数代表整个实数区间的故事很好地捕捉到了 IMO。更一般地说,我们可能会说:Num/Fractional/Floating 是表示整数/有理数/实数的equivalance classes 的类型类。事实上,这些类甚至不需要是“小”区间:特别是像Word32 或标准Int 这样的有限类型可以在modular arithmetic 意义上理解,表现为(2^70 :: Int) == 0 这样的结果,即等价然后类是 264 的倍数的数字空间。

在像IntegerRational 这样的情况下,等价类实际上只包含一个元素,即数字表示完全正确。对于实数,这实际上也是可能的,但更棘手的是,它被称为精确实数运算。有像 aern 这样的库可以做到这一点。

【讨论】:

  • 说“Fractional 类型未连接”是不是有点误导,因为Floating 类型的集合是Fractional 类型的子集(因为class Fractional a => Floating a)?这就像说“携带 DNA/RNA 的东西是活的”,而忘记了病毒(有 RNA 但没有新陈代谢)。
  • @WillemVanOnsem 如果分数类型是浮动的,那么它是连接的,但如果它没有连接,那么它不是浮动的。
  • @JoshLee:是的,我知道:但我认为答案可能有点令人困惑......
  • @WillemVanOnsem 我说的一些 Fractional类型不相连,并举Rational为例。
  • @leftaroundabout: 是的,出于某种原因,我第一次看的时候并没有发现 some :( 可能是因为 Berlinade 截止日期而过度劳累了:)
【解决方案2】:

FractionalFloating的定义可以在Prelude的文档中找到:

class Num a => Fractional a where
    (/) :: a -> a -> a
    recip :: a -> a
    fromRational :: Rational -> a 

小数,支持实除法。

[...]

class Fractional a => Floating a where
    pi :: a
    exp :: a -> a
    log :: a -> a
    sqrt :: a -> a
    (**) :: a -> a -> a
    logBase :: a -> a -> a
    sin :: a -> a
    cos :: a -> a
    tan :: a -> a
    asin :: a -> a
    acos :: a -> a
    atan :: a -> a
    sinh :: a -> a
    cosh :: a -> a
    tanh :: a -> a
    asinh :: a -> a
    acosh :: a -> a
    atanh :: a -> a

三角函数和双曲函数及相关函数。

[...]

所以把它翻译成英文:Fractional 是我可以定义除法的任何类型的数字:

(/) :: Fractional a => a -> a -> a

例如,浮点数可能是这种情况,也可能是分数(其中分数有一个分子分母)。 Int 不是这种情况,因为如果将 Int 除以 Int 并不总是产生 Int(从技术上讲,计算机上的浮点除法并不准确,但那是另一回事了)。

Fractional 数字的子集是定义三角函数的 Floating 数字。例如,分数的sin 不可能总是产生分数:sin 被定义为无限序列的总和。它仅适用于非常有限的情况(例如sin 0)。基本上,计算机上唯一(近似地)定义三角函数的数字是浮点数。

【讨论】:

    猜你喜欢
    • 2016-05-16
    • 2021-06-27
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    • 2016-08-07
    • 1970-01-01
    相关资源
    最近更新 更多