В Haskell есть бесконечность: Num a => a?
Я пытаюсь реализовать структуру данных, где, если бы я использовал бесконечность для численных целей сравнения, это было бы просто очень. Обратите внимание, что это не maxBound/minBound, потому что значение может быть
никакой надежды?
8 ответов
может быть, вы хотите тип может быть?
data Infinite a = Infinite | Only a
затем напишите экземпляр Num для Num a = > Infinite a, с числовыми правилами, которые вам нужны.
Ну как про что! Оказывается, если вы просто наберете 1/0
возвращает Infinity
! На ГГц:
Prelude> 1/0
Infinity
Prelude> :t 1/0
1/0 :: (Fractional t) => t
Prelude> let inf=1/0
Prelude> filter (>=inf) [1..]
и тогда, конечно, он работает вечно, никогда не находя числа больше бесконечности. (Но СМ. комментарии ephemient ниже о фактическом поведении [1..]
)
попробуйте что-то вроде этого. Однако, чтобы получить 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)
взгляните на мой библиотека RangedSets, который делает именно это в очень общем виде. Я определил тип " границы "так, чтобы значение типа" граница a "всегда было выше или ниже любого заданного"a". Границы могут быть "AboveAll", "BelowAll", "выше x"и" ниже x".
Если ваш вариант использования заключается в том, что у вас есть граничные условия, которые иногда нужно проверить, но иногда нет, вы можете решить его следующим образом:
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
существует более принципиальный подход, основанный на идее нестандартного анализа. Учитывая полностью упорядоченное кольцо 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
, с другими тонкостями, которые вы, возможно, хотите, включая + / - бесконечность, + / - бесконечно малый, второго порядка бесконечно малые и т. д.. Но обратите внимание, что это не Архимед, и индукция больше не будет работать, что является своего рода арифметикой второго порядка. Для реализации взгляните на . Как и в комментарии в коде, эта конструкция должна работать для других алгебр, таких как монада списка. Вы можете думать о списках, где два элемента "бесконечно близки", "бесконечно далеки" второго порядка и т. д. (что приводит к обобщению розовых деревьев.)