There are many types of numbers in ATS. With function templates, we can greatly enhance code sharing in numerical computation. For example, we can give a generic implementation of matrix multiplication of the following interface:
fun {a:t@ype} matrix_mul {p,q,r:int} ( p: int(p) , q: int(q) , r: int(r) , A: &matrix(a, p, q) , B: &matrix(a, q, r) , C: &matrix(a?, p, r) >> matrix(a, p, r) ) : void // end of [matrix_mul]
Let us take a look at a concrete example involving generic operations on numbers. The following code gives a standard implementation of the factorial function:
// extern fun fact(n: int): int // implement fact(n) = if n > 0 then n * fact(n-1) else 1 // end of [fact] //
// extern fun factd(n: int): double // implement factd(n) = if n > 0 then n * factd(n-1) else 1.0 // end of [factd] //
// extern fun{a:t@ype} gfact(n: int): a // implement {a}(*tmp*) gfact(n) = ( // if n > 0 then gmul_int_val<a>(n, gfact<a>(n-1)) else gnumber_int<a>(1) // ) (* end of [gfact] *) //
implement {a}(*tmp*) gfact(n) = let // overload * with gmul_int_val // in // if n > 0 then n * gfact<a>(n-1) else gnumber_int<a>(1) // end (* end of [gfact] *)
// #define HX_INTINF_targetloc "$PATSHOME/contrib/atscntrb-hx-intinf" // (* ****** ****** *) // staload _(*T*) = "{$HX_INTINF}/DATS/intinf_t.dats" staload _(*VT*) = "{$HX_INTINF}/DATS/intinf_vt.dats" // staload GINTINF = "{$HX_INTINF}/DATS/gintinf_t.dats" // (* ****** ****** *) // typedef intinf = $GINTINF.intinf overload print with $GINTINF.print_intinf // val () = println! ("gfact<intinf>(100) = ", gfact<intinf>(100)) //
Please find on-line the file gnumber.dats containing the entirety of the code presented in this section plus some testing code.