module Util.IntPlus(
IntPlus,
infinity
) where
data IntPlus = Infinite Bool | Finite Integer deriving Eq
infinity :: IntPlus
infinity = Infinite True
instance Ord IntPlus where
compare i1 i2 = case (i1,i2) of
(Infinite b1,Infinite b2) -> compare b1 b2
(Finite _,Infinite b) -> if b then LT else GT
(Infinite b,Finite _) -> if b then GT else LT
(Finite i1,Finite i2) -> compare i1 i2
instance Show IntPlus where
showsPrec _ (Infinite b) s = if b then "infinity"++s else "-infinity"++s
showsPrec p (Finite i) s = showsPrec p i s
instance Num IntPlus where
(+) i1 i2 = case (i1,i2) of
(Finite i1,Finite i2) -> Finite (i1 + i2)
(Infinite b,Finite _) -> Infinite b
(Finite _,Infinite b) -> Infinite b
(Infinite b1,Infinite b2) ->
if b1 == b2 then Infinite b1 else
error "IntPlus: attempt to subtract infinities of like sign"
(*) i1 i2 = case (i1,i2) of
(Finite i1,Finite i2) -> Finite (i1*i2)
(Finite i,Infinite b) -> mul i b
(Infinite b,Finite i) -> mul i b
(Infinite b1,Infinite b2) -> Infinite (b1 == b2)
where
mul i b = case compare i 0 of
LT -> Infinite (not b)
EQ -> Finite 0
GT -> Infinite b
negate (Finite i) = Finite (negate i)
negate (Infinite b) = Infinite (not b)
abs (Finite i) = Finite (abs i)
abs (Infinite _) = infinity
signum i = case compare i 0 of
LT -> 1
EQ -> 0
GT -> 1
fromInteger i = Finite i