I was going through the Coq book from the maths perspective. I was trying to define a dependently typed function that returned a length list with n trues depending on the number trues we want. Coq complains that things don't have the right type but when I see it if it were to unfold my definitions when doing the type comparison it should have worked but it doesn't. Why?
Code:
Module playing_with_types2.
Inductive Vector {A: Type} : nat -> Type :=
| vnil: Vector 0
| vcons: forall n : nat, A -> Vector n -> Vector (S n).
Definition t {A: Type} (n : nat) : Type :=
match n with
| 0 => @Vector A 0
| S n' => @Vector A (S n')
end.
Check t. (* nat -> Type *)
Check @t. (* Type -> nat -> Type *)
(* meant to mimic Definition g : forall n: nat, t n. *)
Fixpoint g (n : nat) : t n :=
match n with
| 0 => vnil
| S n' => vcons n' true (g n')
end.
End playing_with_types2.
Coq's error:
In environment
g : forall n : nat, t n
n : nat
The term "vnil" has type "Vector 0" while it is expected to have type
"t ?n@{n1:=0}".
Not in proof mode.
i.e. t ?n@{n1:=0} is Vector 0...no?
In this case, it looks like Coq does not manage to infer the return type of the
matchexpression, so the best thing to do is to give it explicitly:Note the added
returnclause.Then the real error message appears:
And this time it is true that in general
t n'is not the same asVector n'becauset n'is stuck (it does not know yet whethern'is0or someS n'').