\chapter{Rational Numbers (with Infinity)}
\begin{verbatim}
$Log: QRationals.lhs,v $
Revision 1.1 2004/08/05 11:12:53 malcolm
Add a regression testsuite for the nhc98 compiler. It isn't very good,
but it is better than nothing. I've been using it for about four years
on nightly builds, so it's about time it entered the repository! It
includes a slightly altered version of the nofib suite.
Instructions are in the README.
Revision 1.3 1999/11/02 16:10:42 simonpj
Haskell 98 changes
Revision 1.2 1996/07/25 21:30:48 partain
Bulk of final changes for 2.01
Revision 1.1 1996/01/08 20:05:18 partain
Initial revision
\end{verbatim}
> module QRationals
> (QRational, (%%), qNumerator, qDenominator,
> qInfinite, qUndefined, qRound, qFinite) where
> import Ratio
> infixl 7 %% , :%%
> prec = 7::Int
> data QRational = Integer :%% Integer deriving (Eq)
> qReduce, (%%) :: Integer -> Integer -> QRational
> qNumerator, qDenominator :: QRational -> Integer
Dealing with the following two functions' cases for $0$ is the only
change to the standard prelude's rational package.
> qReduce x 0 = signum x :%% 0
> qReduce x y = (signum x * (abs x `div` d)) :%% (y `div` d)
> where d = gcd x y
> x %% 0 = signum x :%% 0
> x %% y = qReduce (x * signum y) (abs y)
> qNumerator (x:%%y) = x
> qDenominator (x:%%y) = y
> instance Ord QRational where
> (x:%%y) <= (x':%%y') = x * y' <= x' * y
> (x:%%y) < (x':%%y') = x * y' < x' * y
> instance Num QRational where
> (x:%%y) + (x':%%y') = qReduce (x*y' + x'*y) (y*y')
> (x:%%y) - (x':%%y') = qReduce (x*y' - x'*y) (y*y')
> (x:%%y) * (x':%%y') = qReduce (x * x') (y * y')
> negate (x:%% y) = (-x) :%% y
> abs (x:%% y) = abs x :%% y
> signum (x:%% y) = signum x :%% 1
> fromInteger x = fromInteger x :%% 1
> instance Real QRational where
> toRational (x:%%y) = x%y
> instance Fractional QRational where
> (x:%%y) / (x':%%y') = (x*y') %% (y*x')
> recip (x:%%y) = if x < 0 then (-y):%% (-x) else y:%%x
> fromRational x = numerator x :%% denominator x
> instance Enum QRational where
> enumFrom x = enumFromBy x 1
> enumFromThen x y = enumFromBy x (y - x)
> enumFromBy n k = n : enumFromBy (n+k) k
> instance Read QRational where
> readsPrec p = readParen (p > prec)
> (\r -> [(x%%y,u) | (x,s) <- reads r,
> ("%%",t) <- lex s,
> (y,u) <- reads t ])
> instance Show QRational where
> showsPrec p (x:%%y) = showParen (p > prec) (shows x .
> showString " %% " .
> shows y)
\section{General extras for Rationals}
> qInfinite :: QRational -> Bool
> qInfinite x = qDenominator x == 0 && qNumerator x /= 0
> qUndefined :: QRational -> Bool
> qUndefined x = qDenominator x == 0 && qNumerator x == 0
> qRound :: QRational -> Integer
> qRound x = if qUndefined x || qInfinite x
> then error "qRound: undefined or infinite"
> else (2*qNumerator x + d) `div` (2*d) where d = qDenominator x
> qFinite :: QRational -> Bool
> qFinite x = qDenominator x /= 0
This concludes the slightly extended rational package.
|