Introduction to Programming in ATS: | ||
---|---|---|
<<< Previous | Modularity | Next >>> |
The previous package for rational numbers contains a serious limitation: The type for the integers employed in the representation of rational numbers is fixed to be int. If we ever want to represent rational numbers based on integers of a different type (for instance, lint for long integers or llint for long long integers), then we need to implement another package for rationals based on such integers. It is clearly advantageous to avoid this style of programming as it involves code duplication to a great extent.
The approach we take in this section to implement a package for rational numbers that can address the aforementioned limitation follows the idea of functors in the programming language Standard ML (SML). We first introduce a type definition as follows:
typedef intmod (a:t@ype) = '{ ofint= int -> a , fprint= (FILEref, a) -> void , neg= (a) -> a // negation , add= (a, a) -> a // addition , sub= (a, a) -> a // subtraction , mul= (a, a) -> a // multiplication , div= (a, a) -> a // division , mod= (a, a) -> a // modulo , cmp= (a, a) -> int // comparison } // end of [intmod] |
abst@ype rat (a:t@ype) = (a, a) typedef ratmod (a:t@ype) = '{ make= (a, a) -<cloref1> rat a , fprint= (FILEref, rat a) -<cloref1> void , numer= rat a -> a // numerator , denom= rat a -> a // denominator , neg= (rat a) -<cloref1> rat a // negation , add= (rat a, rat a) -<cloref1> rat a // addition , sub= (rat a, rat a) -<cloref1> rat a // subtraction , mul= (rat a, rat a) -<cloref1> rat a // multiplication , div= (rat a, rat a) -<cloref1> rat a // division , cmp= (rat a, rat a) -<cloref1> int // comparison } // end of [ratmod] |
staload M = "libc/SATS/math.sats" // for [fmod] val intmod_int = '{ ofint= lam (i) => i , fprint= lam (out, x) => fprintf (out, "%i", @(x)) , neg= lam (x) => ~x , add= lam (x, y) => x + y , sub= lam (x, y) => x - y , mul= lam (x, y) => x * y , div= lam (x, y) => x / y , mod= lam (x, y) => op mod (x, y) , cmp= lam (x, y) => compare (x, y) } : intmod (int) // end of [val] val ratmod_int = ratmod_make_intmod<int> (intmod_int) val intmod_dbl = '{ ofint= lam (i) => double_of (i) , fprint= lam (out, x) => fprintf (out, "%0.f", @(x)) , neg= lam (x) => ~x , add= lam (x, y) => x + y , sub= lam (x, y) => x - y , mul= lam (x, y) => x * y , div= lam (x, y) => $M.trunc (x/y) // trunc: truncation , mod= lam (x, y) => $M.fmod (x, y) // the modulo function , cmp= lam (x, y) => compare (x, y) } : intmod (double) // end of [val] val ratmod_dbl = ratmod_make_intmod<double> (intmod_dbl) |
<<< Previous | Home | Next >>> |
Example: A Package for Rationals | Up | Specific Template Implementation |