//
// Course: BU CAS CS 520
// Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
//

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

// this is a non-tail-recursive implementation
fun{a:t@ype} append {m,n:nat} .<m>.
  (xs: list (a, m), ys: list (a, n)):<> list (a, m+n) =
  case+ xs of
  | list_cons (x, xs1) => list_cons (x, append (xs1, ys))
  | list_nil () => ys
// end of [append]

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

// this is a tail-recursive implementation
fn{a:t@ype} append {m,n:nat}
  (xs: list (a, m), ys: list (a, n)):<> list (a, m+n) = let
  fun loop {m:nat} .<m>. (
      xs: list (a, m), ys: list (a, n), res: &List a? >> list (a, m+n)
    ) :<> void =
    case+ xs of
    | list_cons (x, xs1) => let
        val () = res := list_cons {a} {0} (x, ?)
        val list_cons (_, !p_res) = res
        val () = loop (xs1, ys, !p_res)
      in
        fold@ res // this is a no-op; so [loop] is tail-recursive
      end // end of [list_cons]
    | list_nil () => (res := ys)
  // end of [loop]
  var res: List a // unintialized
  val () = loop (xs, ys, res)
in
  res
end // end of [append]


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

(* end of [list.dats] *)