module Z (Z(..), zero, one, negate) where import Base import N (N, n02n, n2n0) import qualified N (one) import qualified N0 (zero) data Z = Zero | Pos N | Neg N deriving (Eq) zero = Zero one = Pos N.one instance Show Z where show a = "Z[" ++ (show . toInteger $ a) ++ "]" n02z n | n == N0.zero = Zero n02z n | otherwise = Pos $ n02n n abs' (Pos a) = a abs' (Neg a) = a instance Num Z where a + b | a == negate b = Zero a + b | a == Zero = b a + b | a > Zero && b >= Zero = Pos $ abs' a + abs' b a + b | a > Zero && b < Zero && abs a > abs b = Pos $ abs' a - abs' b a + b | a > Zero && b < Zero && abs a < abs b = Neg $ abs' b - abs' a a + b | a < Zero && b <= Zero = Neg $ abs' a + abs' b a + b | a < Zero && b > Zero && abs a > abs b = Neg $ abs' a - abs' b a + b | a < Zero && b > Zero && abs a < abs b = Pos $ abs' b - abs' a a - b = a + negate b Zero * _ = Zero _ * Zero = Zero a * b = s (abs' a * abs' b) where s x | a >= Zero && b >= Zero = Pos x s x | a <= Zero && b <= Zero = Pos x s x | otherwise = Neg x abs Zero = Zero abs (Pos n) = Pos n abs (Neg n) = Pos n negate Zero = Zero negate (Pos n) = Neg n negate (Neg n) = Pos n signum Zero = Zero signum (Pos _) = one signum (Neg _) = -one fromInteger 0 = Zero fromInteger n | n > 0 = Pos $ fromInteger n fromInteger n | n < 0 = Neg $ fromInteger (-n) instance Real Z where toRational = toRational . toInteger instance Enum Z where succ a = a + 1 pred a = a - 1 toEnum = fromInteger . fromIntegral fromEnum = fromIntegral . toInteger instance Integral Z where a `div` Zero = error "Division by Z[0]!" a `div` b = s (abs' a `div` abs' b) where s x | a >= Zero && b >= Zero = Pos x s x | a <= Zero && b <= Zero = Pos x s x | otherwise = Neg x toInteger Zero = 0 toInteger (Pos a) = toInteger a toInteger (Neg a) = -toInteger a instance Ord Z where a <= b | a == b = True (Pos _) <= Zero = False (Neg _) <= Zero = True Zero <= Zero = True Zero <= (Pos _) = True Zero <= (Neg _) = False a <= b = a <= (b - one)
Download