Подтвердить что ты не робот

В Haskell существует бесконечность:: Num a => a?

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

Нет надежды?

4b9b3361

Ответ 1

Может быть, вам нужен тип Maybe?

data Infinite a = Infinite | Only a

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

Ответ 2

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

Ответ 3

infinity = read "Infinity"

Ответ 4

Попробуйте что-нибудь подобное. Однако для получения операций 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)

Ответ 5

λ: let infinity = (read "Infinity")::Double
λ: infinity > 1e100
True
λ: -infinity < -1e100
True

Ответ 6

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

Ответ 7

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

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

Ответ 8

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