{-| Module : Numeric.InfInt Copyright : (c) UU, 2019 License : MIT Maintainer : Tom Smeding Stability : experimental Portability : POSIX, macOS, Windows -} module Numeric.InfInt where -- | The integers with ±∞ added. This is not a full ring ('∞ + -∞' is -- undefined, for instance), but it works well enough. data InfInt = MInfinity | Finite Int | Infinity deriving (Show, Eq, Ord) instance Num InfInt where Infinity + MInfinity = undefined Infinity + _ = Infinity MInfinity + Infinity = undefined MInfinity + _ = MInfinity Finite n + Finite m = Finite (n + m) Finite _ + Infinity = Infinity Finite _ + MInfinity = MInfinity Finite n * Finite m = Finite (n * m) Finite 0 * _ = undefined Finite n * Infinity = if n < 0 then MInfinity else Infinity Finite n * MInfinity = if n < 0 then Infinity else MInfinity Infinity * Finite m = Finite m * Infinity Infinity * Infinity = Infinity Infinity * MInfinity = MInfinity MInfinity * Finite m = Finite m * MInfinity MInfinity * Infinity = MInfinity MInfinity * MInfinity = Infinity abs (Finite n) = Finite (abs n) abs _ = Infinity signum (Finite n) = Finite (signum n) signum MInfinity = (-1) signum Infinity = 1 fromInteger n = Finite (fromInteger n) negate (Finite n) = Finite (-n) negate Infinity = MInfinity negate MInfinity = Infinity -- | If the number is finite, return the finite component. toFinite :: InfInt -> Maybe Int toFinite (Finite n) = Just n toFinite Infinity = Nothing toFinite MInfinity = Nothing -- | @isFinite = isJust . toFinite@ isFinite :: InfInt -> Bool isFinite (Finite _) = True isFinite _ = False