1 -- LML original: Sandra Foubister, 1990
    2 -- Haskell translation: Colin Runciman, May 1991
    3 
    4 module Rational(
    5 radd, rsub, rmul, rdiv, rmin, rabs, intval, show_rat, torat) where
    6 --CR removed norm from export list, renamed rmin2 as rmin
    7 
    8 norm :: (Int, Int) -> (Int, Int)
    9 norm (x,y) = (u `div` d, v `div` d)
   10              where
   11              u = if y > 0 then x else -x
   12              v = abs y
   13              d = gcd (abs u) v
   14 
   15              gcd :: Int -> Int -> Int
   16              gcd 0 n2  = n2
   17              gcd n1 0  = n1
   18              gcd n1 n2 = if n1 < n2 then gcd n1 (n2 `mod` n1) else gcd (n1 `mod` n2) n2
   19 
   20 radd, rsub, rmul, rdiv :: (Int, Int) -> (Int, Int) -> (Int, Int)
   21 radd (x,y) (u,v) = norm (x * v + u * y, y * v)
   22 rsub (x,y) (u,v) = norm (x * v - u * y, y * v)
   23 rmul (x,y) (u,v) = norm (x * u, y * v)
   24 rdiv (x,y) (u,v) = norm (x * v, y * u)
   25 
   26 --CR removed unnecessary normalisation, renamed as rmin
   27 rmin (x,y) (u,v) = if a > 0 then (u,v) else (x,y)
   28                    where (a,b) = rsub (x,y) (u,v)
   29 
   30 --CR removed unnecessary normalisation
   31 rabs :: (Int, Int) -> (Int, Int)
   32 rabs (x,y) = if x<0 then (-x,y) else (x,y)
   33 
   34 -- if y is zero we have an error condition
   35 intval :: (Int, Int) -> Int
   36 intval (x,y) = x `div` y
   37 
   38 --for debugging
   39 show_rat :: (Int, Int) -> [Char]
   40 show_rat (x,y) = show x ++ "/" ++ show y  
   41 
   42 torat :: Int -> (Int, Int)
   43 torat n = (n,1)
   44 
   45 
   46