summaryrefslogtreecommitdiff
path: root/src/Numeric
diff options
context:
space:
mode:
Diffstat (limited to 'src/Numeric')
-rw-r--r--src/Numeric/InfInt.hs60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/Numeric/InfInt.hs b/src/Numeric/InfInt.hs
new file mode 100644
index 0000000..871e5eb
--- /dev/null
+++ b/src/Numeric/InfInt.hs
@@ -0,0 +1,60 @@
+{-|
+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