Section type.
Variable eqv : forall x, type (F x).
Global Instance type_hlist (ls : list iT): type (hlist ls) :=
{ equal := @equiv_hlist (fun x => @equal _ (eqv x)) ls
; proper :=
(fix recur ls (h : hlist ls) : Prop :=
match h with
| Hnil => True
| Hcons _ _ x y => proper x /\ recur _ y
end) ls
}.
Variable eqvOk : forall x, typeOk (eqv x).
Global Instance typeOk_hlist (ls : list iT): typeOk (type_hlist ls).
Global Instance proper_hlist_app l l' : proper (@hlist_app l l').
Fixpoint hlist_split ls ls' : hlist (ls ++ ls') -> hlist ls * hlist ls' :=
match ls as ls return hlist (ls ++ ls') -> hlist ls * hlist ls' with
| nil => fun h => (Hnil, h)
| l :: ls => fun h =>
let (a,b) := @hlist_split ls ls' (hlist_tl h) in
(Hcons (hlist_hd h) a, b)
end.
End type.
Polymorphic Fixpoint nth_error_get_hlist_nth (ls : list iT) (n : nat) {struct ls} :
option {t : iT & hlist ls -> F t} :=
match
ls as ls0
return option {t : iT & hlist ls0 -> F t}
with
| nil => None
| l :: ls0 =>
match
n as n0
return option {t : iT & hlist (l :: ls0) -> F t}
with
| 0 =>
Some (@existT _ (fun t => hlist (l :: ls0) -> F t)
l (@hlist_hd _ _))
| S n0 =>
match nth_error_get_hlist_nth ls0 n0 with
| Some (existT x f) =>
Some (@existT _ (fun t => hlist _ -> F t)
x (fun h : hlist (l :: ls0) => f (hlist_tl h)))
| None => None
end
end
end.

Lemma nth_error_get_hlist_nth_appR
: forall tvs' tvs n x,
n >= length tvs ->
nth_error_get_hlist_nth (tvs ++ tvs') n = Some x ->
exists y,
nth_error_get_hlist_nth tvs' (n - length tvs) = Some (@existT _ _ (projT1 x) y) /\
forall vs vs',
(projT2 x) (hlist_app vs vs') = y vs'.