Set Implicit Arguments.
Set Strict Implicit.
Inductive data T : (T -> Type) -> Type :=
| Inj   : forall X, Type -> data X
| Get   : forall X, T -> data X
| Prod  : forall X, data X -> data X -> data X
| Sigma : forall X (S : Type), (S -> data X) -> data X
| Pi    : forall X (S : Type), (S -> data X) -> data X.
Fixpoint dataD (T : Type) (X : T -> Type) (d : data X) : Type :=
match d with
| Inj _X x => x
| Get X i => X i
| Prod l r => prod (dataD l) (dataD r)
| @Sigma _ _ i s => @sigT i (fun v => dataD (s v))
| @Pi _ _ i s => forall v : i, dataD (s v)
end.
(** Example of lists as data **)
Definition dataList (a : Type) : @data unit (fun _ => list a) :=
@Sigma _ _ bool (fun x => match x with
| true => @Inj _ _ unit
| false => @Prod _ _ (Inj _ a) (Get _ tt)
end).

(* Specifications: *)
Theorem dataList_to_list : forall T (x : dataD (dataList T)), list T.
simpl. intros.