Есть ли в Haskell бесконечность :: Num a => a? - PullRequest
26 голосов
/ 01 марта 2010

Я пытаюсь реализовать структуру данных, в которой, если бы я использовал бесконечность для целей числового сравнения, это было бы очень просто. Обратите внимание, что это не maxBound / minBound, поскольку значение может быть <= maxbound, но все значения будут <бесконечность. </p>

Нет надежды?

Ответы [ 8 ]

27 голосов
/ 01 марта 2010

Ну как на счет этого! Оказывается, если вы просто наберете 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..])

20 голосов
/ 02 марта 2010
infinity = read "Infinity"
15 голосов
/ 01 марта 2010

Может быть, вы хотите тип Maybe?

data Infinite a = Infinite | Only a

затем напишите экземпляр Num для Num a => Infinite a с нужными вам числовыми правилами.

6 голосов
/ 01 марта 2010

Попробуйте что-нибудь подобное. Однако для получения Num операций (например, + или -) вам необходимо определить экземпляр Num для типа Infinitable a. Так же, как я сделал это для 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)
4 голосов
/ 14 сентября 2013
λ: let infinity = (read "Infinity")::Double
λ: infinity > 1e100
True
λ: -infinity < -1e100
True
2 голосов
/ 06 марта 2010

Взгляните на мою библиотеку RangedSets , которая делает это в общих чертах. Я определил тип «Граница», чтобы значение типа «Граница а» всегда было либо выше, либо ниже любого данного «а». Границами могут быть «AboveAll», «BelowAll», «Above x» и «Below x».

1 голос
/ 01 марта 2010

Если ваш вариант использования состоит в том, что у вас есть граничные условия, которые иногда нужно проверять, а иногда нет, вы можете решить это следующим образом:

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
0 голосов
/ 25 июля 2017

Существует более принципиальный подход, основанный на идее нестандартного анализа. Для вполне упорядоченного кольца R с нулевой характеристикой можно рассмотреть кольцо Лорана 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, с другими тонкостями, которые вы, возможно, захотите, включая +/- бесконечность, +/- бесконечно малый , бесконечно малые второго порядка и т. д. Но обратите внимание, что это не Архимедиан, и индукция больше не будет работать, что является своего рода арифметикой второго порядка. Для реализации взгляните на этот пример . Как и в комментарии в коде, эта конструкция должна работать для других алгебр, таких как монада списка. Можно придумать списки, в которых два элемента «бесконечно близки», «бесконечно далеки второго порядка» и т. Д. (Что приводит к обобщению розовых деревьев.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...