///|
/// A generic functional list.
pub(all) enum MList[T] {
  Nil
  Cons(T, MList[T])
} derive(Show, Eq)

///|
fn[T] MList::reverse(self : MList[T]) -> MList[T] {
  loop (self, Nil) {
    (Nil, acc) => acc
    (Cons(head, tail), acc) => continue (tail, Cons(head, acc))
  }
}

test "mlist reverse" {
  let list = MList::from_array([1, 2, 3])
  assert_eq(list.reverse(), MList::from_array([3, 2, 1]))
}

///|
/// A zipper for a functional list `MList[T]`.
/// It represents a list with a "focus" on one of its elements.
/// `left` contains elements to the left of the focus, in reverse order.
/// `right` contains elements to the right of the focus.
pub(all) struct Zipper[T] {
  left : MList[T]
  focus : T
  right : MList[T]
} derive(Show, Eq)