(* Sixth version of Rational that does a "lazy" reduce by only reducing in toString *) module type RATIONAL = sig type rational exception Not_a_rational val make_fraction : int * int -> rational val whole : int -> rational val add : rational * rational -> rational val to_string : rational -> string end module Rational : RATIONAL = struct type rational = int * int exception Not_a_rational let rec gcd(x, y) = if x < 0 || y < 0 then gcd(abs(x), abs(y)) else if y = 0 then x else gcd(y, x mod y) let rec reduce_rational(a, b) = if b < 0 then reduce_rational(-a, -b) else let d = gcd(a, b) in (a/d, b/d) let make_fraction(a, b) = if b = 0 then raise Not_a_rational else (a, b) let whole(a) = (a, 1) let add((a, b), (c, d)) = (a * d + c * b, b * d) let to_string(a, b) = let (a2, b2) = reduce_rational(a, b) in if b2 = 1 then string_of_int(a2) else string_of_int(a2) ^ "/" ^ string_of_int(b2) end