//
// Course: BU CAS CS 520, Fall 2010
// Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
// Lecture on Tuesday, Sep. 7, 2010
//

//
// How to compile:
//   atscc-o tally1 tally1.dats
// How to test:
//   ./tally1
//

(* ****** ****** *)

dataprop TALLY (int, int) =
  | TALLYbas (0, 0) of ()
  | {n:nat} {s:int}
    TALLYind (n+1, s+n+1) of TALLY (n, s)
// end of [TALLY]

(*
//
// HX: a standard implementation in tail-recursive style
//
fun tally1 (n: int): int = let
  fun loop (n: int, ans: int): int =
    if n > 0 then loop (n-1, ans+n) else ans
  // end of [loop]
in
  loop (n, 0)
end // end of [tally1]
*)

fun tally1 {n:nat} (n: int n)
  : [s:int] (TALLY (n, s) | int (s)) = let
  fun loop {n:nat} {s0:int}
    (n: int n, ans: int s0)
    : [s:int] (TALLY (n, s) | int (s+s0)) =
    if n > 0 then let
      val (pf1 | ans1) = loop (n-1, ans+n)
    in
      (TALLYind (pf1) | ans1)
    end else (TALLYbas | ans)
  // end of [loop]
in
  loop (n, 0)
end // end of [tally1]

(* ****** ****** *)

implement
main () = () where {
  #define N 100
  val (pf | ans) = tally1 (N)
  val () = printf ("sum(1 ... %i) = %i\n", @(N, ans))
} // end [main]

(* ****** ****** *)

(* end of [tally1.dats] *)