1 (* Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
4 * MLton is released under a BSD-style license.
5 * See the file MLton-LICENSE for details.
7 (*-------------------------------------------------------------------*)
9 (*-------------------------------------------------------------------*)
11 functor Rational(I : INTEGER) : RATIONAL =
19 datatype t = T of I.t * I.t
20 (* always use smallest nonnegative denominator *)
22 fun numerator(T(n,_)) = n
23 fun denominator(T(_,n)) = n
25 fun fromInt n = T(n,I.one)
27 (*fun intTo = ITo o I.intTo*)
28 (*val toInt = I.toInt o toI*)
30 fun isInt q = denominator q = one
33 fun toInt q = if isInt q then numerator q
36 fun toReal(T(p,q)) = I.toReal p / I.toReal q
38 val zero = fromInt I.zero
39 val one = fromInt I.one
41 fun scale(T(p,q),T(p',q')) =
42 let val l = I.lcm(q,q')
48 val (op +) = fn (x,y) =>
49 let val (p,p',l) = scale(x,y)
53 fun inverse(T(p,q)) = if I.isNegative p then T(I.~ q,I.~ p)
56 val (op ~) = fn T(m,n) => T(~m,n)
59 let val g = I.gcd(p,q)
63 fun make(p,q) = T(reduce(p,q))
65 fun intIntTo(m,n) = make(I.fromInt m,I.fromInt n)
67 fun (T(p,q)) * (T(p',q')) =
68 let val (p,q') = reduce(p,q')
69 val (p',q) = reduce(p',q)
70 in T(I.*(p,p'),I.*(q,q'))
74 let val (p,q,_) = scale(x,y)
78 val {<,<=,>,>=,equal,min,max} = Relation.compare compare
82 let val(p,p',q) = scale(x,y)
83 in T(I.random(p,p'),q)
87 fun stringTo _ = raise FromString
88 (*fun toString(T(p,q)) = String.concat[I.toString p,
93 fun input _ = raise Input
96 if isInt p then I.output(toInt p,out)
97 else (I.output(numerator p,out) ;
99 I.output(denominator p,out))
102 structure R = OrderedField(F)