module PreludeInteger(Integer,integerFromInt,intFromInteger,doubleFromInteger,readInteger) where import PreludeNatural import Ratio(intToRat) import Numeric(readSigned,readDec,readHex,readOct,showSigned,showInt) --import Debug.Trace instance Eq Integer where Pos a==Pos b = a==b Neg a==Neg b = a==b a ==b = isZero a && isZero b isZero (Pos a) = isZeroN a isZero (Neg a) = isZeroN a zeroI = Pos zeroN oneI = Pos oneN instance Ord Integer where compare (Pos a) (Pos b) = compare a b compare (Neg a) (Neg b) = compare b a compare (Neg a) (Pos b) = if isZeroN a && isZeroN b then EQ else LT compare (Pos a) (Neg b) = if isZeroN a && isZeroN b then EQ else GT integerFromInt n = if n<zero then if n==minBound then Neg (succ (natFromInt maxBound)) else Neg (natFromInt (-n)) else Pos (natFromInt n) doubleFromInteger (Pos n) = doubleFromNatural n doubleFromInteger (Neg n) = -doubleFromNatural n intFromInteger (Pos n) = intFromNatural n intFromInteger (Neg n) = -intFromNatural n instance Show Integer where showsPrec p (Pos n) = showsPrec p n showsPrec p (Neg n) = showParen (p>six) (showChar '-' . shows n) --show (Pos n) = '+':show n --show (Neg n) = '-':show n instance Enum Integer where toEnum = integerFromInt fromEnum = intFromInteger succ n = n+oneI pred n = n-oneI enumFrom = iterate succ enumFromTo = genericEnumFromTo enumFromThen a b = iterate (+(b-a)) a enumFromThenTo x y z = enumFromStepTo x (y-x) z instance Num Integer where fromInteger = id --fromInt = integerFromInt Pos a + Pos b = Pos (a+b) Neg a + Neg b = Neg (a+b) Pos a + Neg b = case compare a b of LT -> Neg (b-a) EQ -> zeroI GT -> Pos (a-b) Neg a + Pos b = case compare a b of LT -> Pos (b-a) EQ -> zeroI GT -> Neg (a-b) negate (Pos a) = Neg a negate (Neg a) = Pos a Pos a * Pos b = Pos (a*b) Neg a * Neg b = Pos (a*b) Pos a * Neg b = Neg (a*b) Neg a * Pos b = Neg (a*b) abs (Neg a) = Pos a abs a = a signum (Pos a) = if isZeroN a then zeroI else Pos oneN signum (Neg a) = if isZeroN a then zeroI else Neg oneN instance Integral Integer where toInteger = id quotRem = qRemInteger instance Real Integer where toRational = intToRat instance Read Integer where readsPrec d = readSigned (\s->case s of '0':'x':r -> readHex r '0':'o':r -> readOct r _ -> readDec s) readInteger ('-':s) = Neg (readDigits s) readInteger s = Pos (readDigits s) qRemInteger :: Integer -> Integer -> (Integer,Integer) --qRemInteger _ 0 = error "quotRem{Integer}: divide by zero" --qRemInteger 0 _ = (zeroI,zeroI) qRemInteger (Pos ds) (Pos es) = apPair Pos Pos (quotRem ds es) qRemInteger (Neg ds) (Pos es) = apPair Neg Neg (quotRem ds es) qRemInteger (Neg ds) (Neg es) = apPair Pos Neg (quotRem ds es) qRemInteger (Pos ds) (Neg es) = apPair Neg Pos (quotRem ds es) apPair f g (x,y) = (f x,g y)