Definition as_list (e : expr typ func) : option
  ((typ * expr typ func * expr typ func) + typ) :=
match e with
  | Inj (inr (Data (fnil ty))) => Some (inr ty)
  | App (App (Inj (inr (Data (fcons ty)))) hd) tl => Some (inl (ty, hd, tl))
  | _ => None
end.Fixpoint rnth_error (t: typ) (xs: expr typ func) (n: nat) : expr typ func :=
  match as_list xs with
  | Some (inr ty) => none_reif ty
  | Some (inl (ty, hd, tl)) =>
    match n with
    | O => some_reif hd ty
    | S n0 => rnth_error ty tl n0
    end
  | _ => App (Inj (inr (Data (fnth_error t n)))) xs
  end.Fixpoint rreplace_nth (t: typ) (n: nat) (xs: expr typ func) (x: expr typ func) : expr typ func :=
  match as_list xs with
  | Some (inr ty) => xs
  | Some (inl (ty, hd, tl)) =>
    match n with
    | O => App (App (Inj (inr (Data (fcons ty)))) x) tl
    | S n0 => App (App (Inj (inr (Data (fcons ty)))) hd) (rreplace_nth t n0 tl x)
    end
  | _ => App (App (Inj (inr (Data (freplace_nth t n)))) xs) x
  end.Definition reflect tus tvs e (ty : typ)
 := @exprD _ _ _ Expr_expr_fs tus tvs e ty.

(* Specifications: *)
Lemma some_none: forall T v, @None T = Some v -> False.
Lemma as_list_cons : forall e t hd tl, as_list e = Some (inl (t, hd, tl)) -> e = App (App (Inj (inr (Data (fcons t)))) hd) tl.
Lemma as_list_nil : forall e t, as_list e = Some (inr t) -> e = Inj (inr (Data (fnil t))).