【问题标题】:In Haskell, is there infinity :: Num a => a?在 Haskell 中,是否有无穷大 :: Num a => a?
【发布时间】:2011-01-22 05:16:54
【问题描述】:

我正在尝试实现一个数据结构,如果我使用无穷大来进行数值比较,它会变得非常简单。请注意,这不是 maxBound/minBound,因为一个值可以是

没有希望?

【问题讨论】:

    标签: haskell infinity


    【解决方案1】:

    那怎么样!事实证明,如果你只输入1/0,它就会返回Infinity!关于 ghci:

    Prelude> 1/0
    Infinity
    Prelude> :t 1/0
    1/0 :: (Fractional t) => t
    Prelude> let inf=1/0
    Prelude> filter (>=inf) [1..]
    

    然后当然它会永远运行,永远不会找到大于无穷大的数字。 (不过[1..]的实际行为见下文ehemient的cmets)

    【讨论】:

    • IMO,encodeFloat (floatRadix 0 - 1) (snd $ floatRange 0) 是获取Infinity 的更好方法(类型为(RealFrac a) => a)。话虽这么说,由于浮点不精确 [1..] 永远不会超过有限的上限,所以这里的演示很糟糕。
    • 该死。我知道我不应该声称一个程序在看到它运行了有限的时间后会永远运行。
    • 你误会了。在某些时候,尾部将只是[x, x, x, x, x, ..],因为当x 足够大时浮动x+1 == x,即使存在更高的有限y(例如encodeFloat (floatRadix 0 - 1) (snd (floatRange 0) - 1))。显然x < y < inf;我的观点是,这并不是对无穷大的一个很好的证明。
    • 这个也可以写成recip 0
    • @ephemient 我认为这是不正确的,但我不能说你发表评论时是否属实。浮点类型的Enum 的当前实现考虑了这个问题,并且很乐意直接超过您正在谈论的数字(x 其中x + 1 == x)。
    【解决方案2】:
    infinity = read "Infinity"
    

    【讨论】:

    • 如果代码是浮点的,我认为这是最好的答案。人们往往会忘记浮点无穷大。
    【解决方案3】:

    也许你想要一个 Maybe 类型?

    data Infinite a = Infinite | Only a
    

    然后用你需要的数字规则为 Num a => Infinite a 写一个 Num 实例。

    【讨论】:

    • 很明显没有解决方案,所以我基本上采用了你的方法:data Num a => Inf a = NegInf | Val a | PosInf。感谢您的帮助。
    • Nooo,请不要对数据声明施加类型类约束! :-)
    【解决方案4】:

    试试这样的。但是,要获得Num 操作(如+-),您需要为Infinitable a 类型定义Num 实例。就像我为 Ord 班级所做的那样。

    data Infinitable a = Regular a | NegativeInfinity | PositiveInfinity deriving (Eq, Show)
    
    instance Ord a => Ord (Infinitable a) where
        compare NegativeInfinity NegativeInfinity = EQ
        compare PositiveInfinity PositiveInfinity = EQ
        compare NegativeInfinity _ = LT
        compare PositiveInfinity _ = GT
        compare _ PositiveInfinity = LT
        compare _ NegativeInfinity = GT
        compare (Regular x) (Regular y) = compare x y    
    
    main =
        let five = Regular 5
            pinf = PositiveInfinity::Infinitable Integer
            ninf = NegativeInfinity::Infinitable Integer
            results = [(pinf > five), (ninf < pinf), (five > ninf)]
        in
            do putStrLn (show results)
    

    【讨论】:

    • 顺便说一句:如果您首先使用NegativeInfinity 的情况定义Infinitable 数据类型,然后是Regular 和最后的PositiveInfinity,您可以免费派生Ord。 (如果您这样做是为了举一个相对简单的例子,请忽略此评论!)
    【解决方案5】:
    λ: let infinity = (read "Infinity")::Double
    λ: infinity > 1e100
    True
    λ: -infinity < -1e100
    True
    

    【讨论】:

      【解决方案6】:

      看看我的RangedSets library,它以非常通用的方式做到了这一点。我定义了一个“边界”类型,以便“边界 a”类型的值始终高于或低于任何给定的“a”。边界可以是“AboveAll”、“BelowAll”、“Above x”和“Below x”。

      【讨论】:

        【解决方案7】:

        您可以使用提供IEEE typeclassieee754 package。这个类型类有一个infinity 成员。类型类是为FloatDoubleCFloatCDouble 实现的。

        您因此安装了ieee-754 包,然后通过以下方式获得正无穷大(或负无穷大):

        ghci> import Numeric.IEEE
        ghci> infinity :: Double
        Infinity
        ghci> -infinity :: Double
        -Infinity
        

        Floats、Doubles 等为implemented as [src]

            infinity = 1/0
        

        【讨论】:

          【解决方案8】:

          如果您的用例是有时需要检查但有时不需要检查的边界条件,您可以这样解决:

          type Bound a = Maybe a
          
          withinBounds :: (Num a, Ord a) => Bound a -> Bound a -> a -> Bool
          withinBounds lo hi v = maybe True (<=v) lo && maybe True (v<=) hi
          

          【讨论】:

            【解决方案9】:

            基于非标准分析的想法,有一种更有原则的方法。给定一个特征为零的全序环 R,您可以考虑具有自然词典全序的 Laurent 环 R[inf,1/inf]。例如,您有:

            for all x>0 in R,
            .. -inf < -x < -d < -d^2 < .. < 0 < .. < d^2 < d < x < inf < inf^2 < .. 
            where d = 1/inf.
            

            这样,洛朗环 R[inf,1/inf] 又是一个完全有序的 Z 代数,即 Num 的一个实例,还有您可能想要的其他细节,包括 +/-infinity、+/-infinitesimal ,二阶无穷小等。但请注意,它不是阿基米德,归纳将不再起作用,这是一种二阶算术。有关实施,请查看this example。就像代码中的注释一样,这种构造应该适用于其他代数,例如 list monad。您可以想到两个元素“无限接近”“二阶无限远”等的列表(这导致了玫瑰树的泛化。)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-04-14
              • 1970-01-01
              • 2021-11-19
              • 2019-08-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多