[project @ 1996-01-18 16:33:17 by partain]
[ghc-hetmet.git] / ghc / lib / prelude / IRatio.hs
index 53cbeee..3146516 100644 (file)
@@ -15,6 +15,8 @@ import List           ( iterate, (++), foldr, takeWhile )
 import Prel            ( (&&), (||), (.), otherwise, gcd, fromIntegral, id )
 import PS              ( _PackedString, _unpackPS )
 import Text
+import TyArray
+import TyComplex
 
 --infixl 7  %, :%
 
@@ -32,8 +34,8 @@ denominator (x:%y)    =  y
 
 x % y                  =  reduce (x * signum y) (abs y)
 
-reduce _ 0             =  error "(%){PreludeRatio}: zero denominator\n"
-reduce x y             =  (x `quot` d) :% (y `quot` d)
+reduce x y | y == __i0 =  error "(%){PreludeRatio}: zero denominator\n"
+           | otherwise =  (x `quot` d) :% (y `quot` d)
                           where d = gcd x y
 
 instance (Integral a) => Eq (Ratio a) where
@@ -61,67 +63,88 @@ instance (Integral a) => Num (Ratio a) where
     (x1:%y1) * (x2:%y2)        =  reduce (x1 * x2) (y1 * y2)
     negate (x:%y)      =  (-x) :% y
     abs (x:%y)         =  abs x :% y
-    signum (x:%y)      =  signum x :% 1
-    fromInteger x      =  fromInteger x :% 1
-    fromInt x          =  fromInt x :% 1
+    signum (x:%y)      =  signum x :% __i1
+    fromInteger x      =  fromInteger x :% __i1
+    fromInt x          =  fromInt x :% __i1
 
 instance (Integral a) => Real (Ratio a) where
     toRational (x:%y)  =  toInteger x :% toInteger y
 
 instance (Integral a) => Fractional (Ratio a) where
     (x1:%y1) / (x2:%y2)        =  (x1*y2) % (y1*x2)
-    recip (x:%y)       =  if x < 0 then (-y) :% (-x) else y :% x
+    recip (x:%y)       =  if x < __i0 then (-y) :% (-x) else y :% x
     fromRational (x:%y) =  fromInteger x :% fromInteger y
 
-instance (Integral a) => RealFrac (Ratio a) where
-    properFraction (x:%y) = (fromIntegral q, r:%y)
-                           where (q,r) = quotRem x y
-
-    -- just call the versions in Core.hs
-    truncate x =  _truncate x
-    round x    =  _round x
-    ceiling x  =  _ceiling x
-    floor x    =  _floor x
 
 instance (Integral a) => Enum (Ratio a) where
-    enumFrom            = iterate ((+)1)
-    enumFromThen n m    = iterate ((+)(m-n)) n
-    enumFromTo n m      = takeWhile (<= m) (enumFrom n)
-    enumFromThenTo n m p = takeWhile (if m >= n then (<= p) else (>= p))
-                                    (enumFromThen n m)
+    enumFrom            =  iterate ((+) __i1)
+    enumFromThen n m    =  iterate ((+) (m-n)) n
+    enumFromTo n m      =  takeWhile (<= m) (enumFrom n)
+    enumFromThenTo n m p =  takeWhile (if m >= n then (<= p) else (>= p))
+                                     (enumFromThen n m)
 
 instance  (Integral a) => Text (Ratio a)  where
     readsPrec p  =  readParen (p > prec)
-                             (\r -> [(x%y,u) | (x,s)   <- reads r,
+                             (\r -> [(x%y,u) | (x,s)   <- readsPrec 0 r,
                                                ("%",t) <- lex s,
-                                               (y,u)   <- reads t ])
+                                               (y,u)   <- readsPrec 0 t ])
 
     showsPrec p (x:%y) =  showParen (p > prec)
-                              (shows x . showString " % " . shows y)
+                              (showsPrec 0 x . showString " % " . showsPrec 0 y)
+
+    readList   = _readList (readsPrec 0)
+    showList   = _showList (showsPrec 0) 
 
 {-# SPECIALIZE instance Eq         (Ratio Integer) #-}
 {-# SPECIALIZE instance Ord        (Ratio Integer) #-}
 {-# SPECIALIZE instance Num        (Ratio Integer) #-}
 {-# SPECIALIZE instance Real       (Ratio Integer) #-}
 {-# SPECIALIZE instance Fractional  (Ratio Integer) #-}
-{-# SPECIALIZE instance RealFrac    (Ratio Integer) #-}
 {-# SPECIALIZE instance Enum       (Ratio Integer) #-}
 {-# SPECIALIZE instance Text       (Ratio Integer) #-}
 
-{- ToDo: Ratio Int# ???
-#if defined(__UNBOXED_INSTANCES__)
+-- We have to give a real overlapped instance for RealFrac (Ratio Integer)
+-- since we need to give SPECIALIZE pragmas
+
+-- ToDo: Allow (ignored) SPEC pragmas in poly instance]
+--       and substitute for tyvars in a SPECIALIZED instance
+
+instance RealFrac (Ratio Integer) where
+
+    {-# SPECIALIZE properFraction :: Rational -> (Int, Rational) #-}
+    {-# SPECIALIZE truncate :: Rational -> Int #-}
+    {-# SPECIALIZE round    :: Rational -> Int #-}
+    {-# SPECIALIZE ceiling  :: Rational -> Int #-}
+    {-# SPECIALIZE floor    :: Rational -> Int #-}
+
+    {-# SPECIALIZE properFraction :: Rational -> (Integer, Rational) #-}
+    {-# SPECIALIZE truncate :: Rational -> Integer #-}
+    {-# SPECIALIZE round    :: Rational -> Integer #-}
+    {-# SPECIALIZE ceiling  :: Rational -> Integer #-}
+    {-# SPECIALIZE floor    :: Rational -> Integer #-}
+
+    properFraction (x:%y) = case quotRem x y of
+                             (q,r) -> (fromIntegral q, r:%y)
+
+    truncate x = case properFraction x of
+                    (n,_) -> n
+
+    round x    = case properFraction x of
+                    (n,r) -> let
+                               m         = if r < __i0 then n - __i1 else n + __i1
+                               half_down = abs r - __rhalf
+                             in
+                             case (_tagCmp half_down __i0) of
+                               _LT -> n
+                               _EQ -> if even n then n else m
+                               _GT -> m
+
+    ceiling x   = case properFraction x of
+                   (n,r) -> if r > __i0 then n + __i1 else n
 
-{-# SPECIALIZE instance Eq         (Ratio Int#) #-}
-{-# SPECIALIZE instance Ord        (Ratio Int#) #-}
-{-# SPECIALIZE instance Num        (Ratio Int#) #-}
-{-# SPECIALIZE instance Real       (Ratio Int#) #-}
-{-# SPECIALIZE instance Fractional  (Ratio Int#) #-}
-{-# SPECIALIZE instance RealFrac    (Ratio Int#) #-}
-{-# SPECIALIZE instance Enum       (Ratio Int#) #-}
-{-# SPECIALIZE instance Text       (Ratio Int#) #-}
+    floor x    = case properFraction x of
+                   (n,r) -> if r < __i0 then n - __i1 else n
 
-#endif
--}
 
 -- approxRational, applied to two real fractional numbers x and epsilon,
 -- returns the simplest rational number within epsilon of x.  A rational
@@ -134,8 +157,7 @@ instance  (Integral a) => Text (Ratio a)  where
 -- and abs r' < d', and the simplest rational is q%1 + the reciprocal of
 -- the simplest rational between d'%r' and d%r.
 
---{-# GENERATE_SPECS approxRational a{Double#,Double} #-}
-{-# GENERATE_SPECS approxRational a{Double} #-}
+{-# GENERATE_SPECS approxRational a{Double#,Double} #-}
 approxRational :: (RealFrac a) => a -> a -> Rational
 
 approxRational x eps   =  simplest (x-eps) (x+eps)
@@ -143,13 +165,13 @@ approxRational x eps      =  simplest (x-eps) (x+eps)
                           | x == y     =  xr
                           | x > 0      =  simplest' n d n' d'
                           | y < 0      =  - simplest' (-n') d' (-n) d
-                          | otherwise  =  0 :% 1
+                          | otherwise  =  __i0
                                        where xr@(n:%d) = toRational x
                                              (n':%d')  = toRational y
 
              simplest' n d n' d'       -- assumes 0 < n%d < n'%d'
-                       | r == 0     =  q :% 1
-                       | q /= q'    =  (q+1) :% 1
+                       | r == __i0  =  q :% __i1
+                       | q /= q'    =  (q + __i1) :% __i1
                        | otherwise  =  (q*n''+d'') :% n''
                                     where (q,r)      =  quotRem n d
                                           (q',r')    =  quotRem n' d'