The core of ATS is a functional language in which functions are first-class values. A higher-order function is a function whose arguments also include functions.
Let us use BT to range over base types such as char, double, int, string, etc. A simple type T is formed according to the following inductive definition:
As an example, we implement as follows a 2nd-order function find_root that takes a function f from integers to integers as its argument and searches for a root of f by enumeration:
fn find_root (f: int -<cloref1> int): int = let
fun aux (f: int -<cloref1> int, n: int): int =
if f (n) = 0 then n else begin
if n <= 0 then aux (f, ~n + 1) else aux (f, ~n)
end
in
aux (f, 0)
end // end of [fint_root]
The function
find_root computes f(0), f(1), f(-1),
f(2), f(-2), ... until it finds the first integer
i satisfying f(i) = 0.
As another example, we implement the Newton-Raphson's method for finding roots of functions on reals:
val epsilon = 1E-6 (* precision *)
// Newton-Raphson's method for finding roots
// [f1] is a derivative of [f]
fn newton_raphson (
f: double -<cloref1> double
, f1: double -<cloref1> double
, x0: double
) : double = let
fun loop (
f: double -<cloref1> double
, f1: double -<cloref1> double
, x0: double
): double = let
val y0 = f x0
in
if abs (y0 / x0) < epsilon then x0 else begin
let val y1 = f1 x0 in loop (f, f1, x0 - y0 / y1) end
end
end // end of [loop]
in
loop (f, f1, x0)
end // end of [newton_raphson]
// square root function
fn sqrt (c: double): double =
newton_raphson (lam x => x * x - c, lam x => 2.0 * x, 1.0)
// cubic root function
fn cbrt (c: double): double =
newton_raphson (lam x => x * x * x - c, lam x => 3.0 * x * x, 1.0)
The code used for illustration is available here.