Haskell中的Floating类和Fractional类有什么区别?

20

在Haskell中,Floating类和Fractional类有什么区别?


它们在 Prelude 中紧挨着彼此。 - Josh Lee
你确切想要表达什么? - joseabp91
文档上真的没有信息吗? - Blackbam
此问题无需更多信息。 - joseabp91
1
文档确实非常差。 - ZhekaKozlov
潜在的投票者:这个问题绝对不是不清楚的。 - duplode
2个回答

12
非常粗略:
  • Fractional 是能够表示任何有理数的类型的类(精确地或至少在一个良好的近似值)。它也可以表示其他数字,但这不重要。
    从另一方面来说,它只是具有除法运算的数字类型的类别;由于它是Num的子类,因此这意味着该类型必须包含有理数。

  • Floating 是在Cauchy意义下封闭于极限的数字类型的类别,即完备空间。这对于进行任何形式的微积分都是必要的。 Floating 类的方法是作为极限数学上定义的函数,即无穷和(它们是泰勒级数的部分和序列的极限)。
    由于您可以将实数定义为有理数序列的极限,并且再次FloatingFractional的子类,因此任何Floating类型都能够表示(再次提醒,至少在一个良好的近似值下)任何实数

一个很好的区分方法是通过拓扑学:浮点类型是连通空间,即它们形成一个连续体。对于浮点数来说,这意味着每个值都被理解为实数的整个区间(因为浮点数始终存在一定的不确定性)。当你将这些区间并排放置时,你可以用没有间隙的方式铺满整个实数(至少到±10300)。
相比之下,一些分数类型是不连通的。特别地,有理数可以精确地表示所有它的(有理数)值,所以每个值只是一个“无限小的点”。你永远不能用这样的点覆盖整个实数线,也不能计算像sinlog这样的函数,因为这些函数的结果通常是一个非有理实数。

值得思考一下这个“相当接近”的含义。Haskell标准没有定义这个。每个浮点数代表一个实数区间的故事很好地捕捉了它。更一般地说,我们可以说:Num/Fractional/Floating是表示整数/有理数/实数等价类的类型类。事实上,这些类别甚至不必是“小”的区间:特别是像Word32或标准的Int这样的有限类型可以用模算术的意义来理解,表现为结果如(2^70 :: Int) == 0,即等价类是2的64次幂的倍数。

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

说“*分数类型不相关*”是不是有点误导人了,因为浮点类型的集合是分数类型的子集(因为class Fractional a => Floating a)?这就像说“携带DNA/RNA的东西是活的”,却忘记了病毒(它们有RNA但没有新陈代谢)。 - Willem Van Onsem
@WillemVanOnsem 如果一个分数类型是浮点型,那么它就是连接的,但如果它没有连接,那么它就不是浮点型。 - Josh Lee
@JoshLee:是的,我知道:但我认为答案可能会有点令人困惑到那个程度... - Willem Van Onsem
@WillemVanOnsem 我说“一些”分数类型没有联系,并举了有理数作为例子。 - leftaroundabout
@leftaroundabout:是的,可能因为柏林电影节的截止日期,我有点过度劳累,第一次看时没有注意到some :( - Willem Van Onsem

9

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

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

Fractional numbers, supporting real division.

[...]

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

Trigonometric and hyperbolic functions and related functions.

[...]

所以,将其翻译成英语:一个Fractional是我可以定义除法的任何数字类型:

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

这可能适用于浮点数,也适用于分数(其中分数有一个分子分母)。但对于Int来说就不是这样了,因为如果将Int除以Int,并不总是会产生一个Int(虽然在计算机上进行浮点除法不是精确的,但这又是另一回事)。

Fractional数字的一个子集是Floating数字,其中三角函数被定义。例如,一个分数的sin总是产生分数是不可能的:一个sin被定义为无限序列的总和。只有在极少数情况下(如sin 0),才能成立。基本上,在计算机上唯一可以(近似地)定义三角函数的数字是浮点数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接