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

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

dataviewtype llist (a:t@ype) =
  | llist_cons (a) of (a, llist a)
  | llist_nil (a) of ()

(*
// this implementation also frees the given list
fun{a:t@ype}
  llist_length (xs: llist a): int =
  case+ xs of
  | ~llist_cons (_, xs1) => 1 + llist_length (xs1)
  | ~llist_nil () => 0
// end of [llist_length]
*)

(*
// this is a non-tail-recursive implementation
fun{a:t@ype}
  llist_length (xs: !llist a): int =
  case+ xs of
  | llist_cons (_, !p_xs1) => let
      val res = 1 + llist_length (!p_xs1)
    in
      fold@ xs; res
    end
  | llist_nil () => (fold@ xs; 0)
// end of [llist_length]
*)

// this is a tail-recursive implementation
fun{a:t@ype}
  llist_length (xs: !llist a): int = let
  fun loop (xs: !llist a, res: int): int =
    case+ xs of
    | llist_cons (_, !p_xs1) => let
        val res = loop (!p_xs1, res + 1) in fold@ xs; res
      end // end of [llist_cons]
   | llist_nil () => (fold@ xs; res)
in
  loop (xs, 0)
end // end of [llist_length]
// end of [llist_length]

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

(* end of [llist.dats] *)