module BasicNumber (BasicNumber (..), makeReal, makeRational, RealT{-partain-}) where import RealM import Ratio--1.3 data BasicNumber = BasIntegerC Integer | BasRationalC Rational | BasRealC RealT -- deriving () makeReal (a@(BasRealC _)) = a makeReal (BasRationalC a) = if (numerator a) == 0 then BasRealC (int2Real 0) else BasRealC (divReal (int2Real (numerator a)) (int2Real (denominator a))) makeReal (BasIntegerC a) = BasRealC (int2Real a) ------------------------------------------------------------------------------- makeRational (a@(BasRationalC _)) = a makeRational (BasIntegerC a) = BasRationalC (a % 1) ------------------------------------------------------------------------------- instance Eq BasicNumber where (BasRealC _) == _ = error "(==) : Real Numbers cannot\ \ be compared" _ == (BasRealC _) = error "(==) : Real Numbers cannot\ \ be compared" (BasRationalC a) == (BasRationalC b) = a == b (BasRationalC a) == (BasIntegerC b) = a == (b % 1) (BasIntegerC a) == (BasRationalC b) = (a % 1) == b (BasIntegerC a) == (BasIntegerC b) = a == b ------------------------------------------------------------------------------- instance Ord BasicNumber where (BasRealC _) < _ = error "(<) : Real Numbers cannot\ \ be compared" _ < (BasRealC _) = error "(==) : Real Numbers cannot\ \ be compared" (BasRationalC a) < (BasRationalC b) = a < b (BasRationalC a) < (BasIntegerC b) = a < (b % 1) (BasIntegerC a) < (BasRationalC b) = (a % 1) < b (BasIntegerC a) < (BasIntegerC b) = a < b --------------------------------------------------------------------------- (BasRealC _) <= _ = error "(<=) : Real Numbers cannot\ \ be compared" _ <= (BasRealC _) = error "(<=) : Real Numbers cannot\ \ be compared" (BasRationalC a) <= (BasRationalC b) = a <= b (BasRationalC a) <= (BasIntegerC b) = a <= (b % 1) (BasIntegerC a) <= (BasRationalC b) = (a % 1) <= b (BasIntegerC a) <= (BasIntegerC b) = a <= b ------------------------------------------------------------------------------- instance Num BasicNumber where (BasRealC a) + b = BasRealC (addReal a c) where (BasRealC c) = makeReal b a + (BasRealC b) = BasRealC (addReal c b) where (BasRealC c) = makeReal a (BasRationalC a) + b = BasRationalC (a + c) where (BasRationalC c) = makeRational b a + (BasRationalC b) = BasRationalC (c + b) where (BasRationalC c) = makeRational a (BasIntegerC a) + (BasIntegerC b) = BasIntegerC (a + b) --------------------------------------------------------------------------- (BasRealC a) - b = BasRealC (subReal a c) where (BasRealC c) = makeReal b a - (BasRealC b) = BasRealC (subReal c b) where (BasRealC c) = makeReal a (BasRationalC a) - b = BasRationalC (a - c) where (BasRationalC c) = makeRational b a - (BasRationalC b) = BasRationalC (c - b) where (BasRationalC c) = makeRational a (BasIntegerC a) - (BasIntegerC b) = BasIntegerC (a - b) --------------------------------------------------------------------------- negate a = (BasIntegerC 0) - a --------------------------------------------------------------------------- (BasRealC a) * b = BasRealC (mulReal a c) where (BasRealC c) = makeReal b a * (BasRealC b) = BasRealC (mulReal c b) where (BasRealC c) = makeReal a (BasRationalC a) * b = BasRationalC (a * c) where (BasRationalC c) = makeRational b a * (BasRationalC b) = BasRationalC (c * b) where (BasRationalC c) = makeRational a (BasIntegerC a) * (BasIntegerC b) = BasIntegerC (a * b) --------------------------------------------------------------------------- abs (BasRealC _) = error "abs : Operation not defined on reals" abs (BasRationalC a) = BasRationalC (abs a) abs (BasIntegerC a) = BasIntegerC (abs a) --------------------------------------------------------------------------- signum (BasRealC _) = error "signum : Operation not defined on reals" signum (BasRationalC a) = BasRationalC (signum a) signum (BasIntegerC a) = BasIntegerC (signum a) --------------------------------------------------------------------------- fromInteger n = BasIntegerC n ------------------------------------------------------------------------------- instance Enum BasicNumber where enumFrom n = iterate (+1) n enumFromThen n m = iterate (+(m-n)) n instance Real BasicNumber where toRational (BasRealC _) = error "toRational : Real cannot be coerced\ \ to rational" toRational (BasRationalC a) = a toRational (BasIntegerC a) = a % 1 ------------------------------------------------------------------------------- instance Fractional BasicNumber where (BasRealC a) / b = BasRealC (divReal a c) where (BasRealC c) = makeReal b a / (BasRealC b) = BasRealC (divReal c b) where (BasRealC c) = makeReal a (BasRationalC a) / b = BasRationalC (a / c) where (BasRationalC c) = makeRational b a / (BasRationalC b) = BasRationalC (c / b) where (BasRationalC c) = makeRational a (BasIntegerC a) / (BasIntegerC b) = BasRationalC (a % b) --------------------------------------------------------------------------- fromRational a = BasRationalC a ------------------------------------------------------------------------------- instance Floating BasicNumber where sqrt a = BasRealC (sqrtReal b) where (BasRealC b) = makeReal a --------------------------------------------------------------------------- pi = error "pi : Not yet implemented" exp = error "exp : Not yet implemented" log = error "log : Not yet implemented" sin = error "sin : Not yet implemented" cos = error "cos : Not yet implemented" asin = error "asin : Not yet implemented" acos = error "acos : Not yet implemented" atan = error "atan : Not yet implemented" sinh = error "sinh : Not yet implemented" cosh = error "cosh : Not yet implemented" asinh = error "asinh : Not yet implemented" acosh = error "acosh : Not yet implemented" atanh = error "atanh : Not yet implemented" ------------------------------------------------------------------------------- instance Show BasicNumber where showsPrec _ (BasRealC x) s = intPart ++ "." ++ fracPart ++ s where evalX = show (evalReal x (-10)) lenBeforeDecimal = (length evalX) - 10 intPart = if lenBeforeDecimal <= 0 then "0" else take lenBeforeDecimal evalX fracPart = if lenBeforeDecimal < 0 then (pad (- lenBeforeDecimal) '0') ++ evalX else drop lenBeforeDecimal evalX pad 0 a = [] --WAS:pad (n+1) a = a:(pad n a) pad n a = a:(pad (n-1) a) showsPrec _ (BasRationalC x) s = shows x s showsPrec _ (BasIntegerC x) s = shows x s --------------------------------------------------------------------------- instance Read BasicNumber where readsPrec p s = if allZeros frac then map int2BasNum (readsPrec p int) else map rat2BasNum (readsPrec p s) where (int, frac) = span (\c -> c /= '.') s allZeros "" = True allZeros (c:fs) | (c >= '1') && (c <= '9') = False allZeros (c:fs) = allZeros fs int2BasNum (num, s) = (BasIntegerC num, s) rat2BasNum (num, s) = (BasRationalC (approxRational num 0), s) -------------------------------------------------------------------------------