Require Import List. Import ListNotations. Fixpoint hlist (l:list Type):Type := match l with | [] => unit | t::ts => t * (hlist ts) end. Definition hd {t:Type} {ts:list Type} (l:hlist (t::ts)) : t := fst l. Definition tl {t:Type} {ts:list Type} (l:hlist (t::ts)) : hlist ts := snd l. Definition hnil : hlist [] := tt. Definition hcons {t:Type} {ts:list Type} (a:t) : hlist ts -> hlist (t::ts) := match ts with | [] => fun _ => (a, tt) | (x::xs) => fun hl => (a, hl) end. Fixpoint append {ts1 ts2:list Type} : hlist ts1 -> hlist ts2 -> hlist (ts1 ++ ts2) := match ts1 with | [] => fun _ => fun hl2 => hl2 | t::ts => fun hl1 => fun hl2 => (*hcons (hd hl1) (append (tl hl1) hl2)*) (hd hl1, append (tl hl1) hl2) end. Example foo0 : hlist [nat:Type] := (2,tt). Compute hcons 3 foo0. (* = (3, (2, tt)) : hlist [nat; nat : Type] *) Compute hcons true (hcons 3 foo0). (* = (true, (3, (2, tt))) : hlist [bool; nat; nat : Type] *) Example foo1 : hlist [nat:Type; bool:Type] := (2,(true,tt)). Compute append foo1 foo0. (* = (2, (true, (2, tt))) : hlist ([nat : Type; bool : Type] ++ [nat : Type]) *) Compute append foo1 (hcons 3 foo0). (* = (2, (true, (3, (2, tt)))) : hlist ([nat : Type; bool : Type] ++ [nat; nat : Type]) *)