(* CSE 341, Marty Stepp A structure represents a reusable module of ML code. This structure contains a data type to represent rational numbers (fractions) and associated functions to process them. Example usage: val r1 = Rational.Fraction(1, 3); val r2 = Rational.Fraction(2, 12); val r3 = Rational.add(r1, r2); (* 1/2 *) *) structure Rational = struct datatype rational = Whole of int | Fraction of int * int; (* Produces the greatest common divisor (largest common factor) of a and b. *) fun gcd(a, 0) = a | gcd(a, b) = gcd(b, a mod b); (* Converts a rational number into reduced form, e.g. turns 4/12 into 1/3. *) fun reduce(Whole(a)) = Whole(a) | reduce(Fraction(a, b)) = let val g = gcd(a, b) in Fraction(a div g, b div g) end; (* Adds the two given rational numbers and produces the result. The result is given in 'reduced' form (e.g. 1/3 not 4/12). *) fun add(Whole(a), Whole(b)) = Whole(a+b) | add(Whole(a), Fraction(b, c)) = Fraction(a*c+b, c) | add(Fraction(b, c), Whole(a)) = Fraction(a*c+b, c) | add(Fraction(a, b), Fraction(c, d)) = reduce(Fraction(a*d+b*c, b*d)); (* Converts a rational number into a string such as "1/3". *) fun toString(Whole(a)) = Int.toString(a) | toString(Fraction(a, b)) = Int.toString(a) ^ "/" ^ Int.toString(b); end;