Here I present two ways to write Euler's totient function in ATS. First we write our primality check:

#include "share/atspre_staload.hats"

staload "libats/libc/SATS/math.sats" staload UN = "prelude/SATS/unsafe.sats"

fn witness(n : int) :<> [ m : nat ] int(m) = $UN.cast(n)

fn sqrt_int(k : intGt(0)) :<> [ m : nat ] int(m) = let var bound: int = g0float2int(sqrt_float(g0int2float(k))) in witness(bound) end

fn is_prime(k : intGt(0)) :<> bool = case+ k of | 1 => false | k => begin let fnx loop {n : nat}{m : nat} .<max(0,m-n)>. (i : int(n), bound : int(m)) :<> bool = if i < bound then if k % i = 0 then false else loop(i + 1, bound) else if i = bound then if k % i = 0 then false else true else true in loop(2, sqrt_int(k)) end end

Note the use of witness to introduce the existential, which is needed in assure the compiler that sqrt_int(k) is positive and hence that the termination metric is well-founded (as sqrt_int(k) is used as an input to loop). The :<> in type signatures indicates a function that cannot have side-effects; in ATS this means that the function is guaranteed to terminate (a stronger condition than Haskell's purity).

Now we can implement the actual totient function. Our first example uses relatively straightforward recursion:

fn totient(n : intGte(1)) : int = case+ n of | 1 => 1 | n =>> begin let fnx loop { k : nat | k >= 2 }{ m : nat | m > 0 && k >= m } .<k-m>. (i : int(m), n : int(k)) : int = if i >= n then if is_prime(n) then n - 1 else n else if n % i = 0 && is_prime(i) && i != n then (loop(i + 1, n) / i) * (i - 1) else loop(i + 1, n) in loop(1, n) end end

And again using explicit stack allocation:

fn totient(n : intGte(1)) : int = case+ n of | 1 => 1 | n =>> begin let fnx loop { k : nat | k >= 2 }{ m : nat | m > 0 && k >= m }{l : addr} .<k-m>. ( pf : !int @ l | i : int(m) , n : int(k) , res : ptr(l) ) : void = if i >= n then if is_prime(n) then let val () = !res := n - 1 in end else let val () = !res := n - 1 in end else if n % i = 0 && is_prime(i) && i != n then let val () = !res := (!res / i) * (i - 1) in loop(pf | i + 1, n, res) end else loop(pf | i + 1, n, res)

      var res: int with pf = 1
      val () = loop(pf | 1, n, addr@res)
    in
      res
    end
  end

Just for fun, here's how to implement the totient function in Haskell:

hsIsPrime :: (Integral a) => a -> Bool hsIsPrime 1 = False hsIsPrime x = all ((/=0) . (x mod)) [2..m] where m = floor (sqrt (fromIntegral x :: Float))

hsTotient :: (Integral a) => a -> a hsTotient n = (n * product [ p - 1 | p <- ps ]) div product ps where ps = filter (\k -> hsIsPrime k && n mod k == 0) [2..n]

The Haskell is a good deal slower, but there are certainly advantages in brevity as well.